dp 优化 F2. Pictures with Kittens (hard version)

时间:2023-01-13 16:33:18

dp的优化可能是自己的弱项吧

F1中n*n*n的复杂度强行过去了 

F2就无能为力了;

状态转移

dp[ i ] [ j ] 第一个i存的是位置  1-n;    j是放入数字的个数   然后F1就暴力过去了

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=+;
int dp[maxn][maxn];
int a[maxn];
int32_t main()
{
int n,k,x; cin>>n>>k>>x;
for(int i=;i<=n;i++) cin>>a[i];
dp[][]=;
for(int i=;i<=n;i++)
{
//cout<<" "<<i<<endl;
//cout<<" "<<i-k+1<<endl;
for(int j=i-k;j<i;j++)
{
if(j<) continue;
for(int q=(i-)/k;q<x;q++)
{
if(dp[j][q]||i<=k) dp[i][q+]=max(dp[i][q+],dp[j][q]+a[i]);
}
} }
int maxn=;
for(int i=n;i>=n-k+;i--)
{
maxn=max(dp[i][x],maxn);
}
if(maxn) cout<<maxn<<endl;
else cout<<-<<endl;
}

暴力的F1

然后F2  gg了

看了别人的代码  大致有几种写法

双端队列优化   deque<pair<int,int> >  de[maxn];

写的不难懂点   de[  ]  [  ]  [   ]  大致就是这样存的  de[ ] 这个表示的是 存的数字个数  第二个括号存的是 第i个位置j个数的最大值; 第三个括号存的是  位置 

第i个位置是由 前[ i-k,i-1 ]位置的地方转移过来的;

从  de[j]  到 de[j+1]   必须确定  de[j+1] 已经转移了  所以第二层转移就是   j=x-1; j>=0;j--;

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=5e3+;
int a[maxn];
deque<pair<int,int> > de[maxn];
int32_t main()
{
//priority_queue(int,vector<int>,greater<int>) qu;
int n,k,x; cin>>n>>k>>x;
for(int i=;i<=n;i++) cin>>a[i];
int ans=-;
de[].push_back({,}) ; // first  cun zhi second pos;
for(int i=;i<=n;i++)
{
for(int j=x-;j>=;j--)
{
while(!de[j].empty() && de[j].front().second<i-k ) de[j].pop_front(); // i-k
if(de[j].empty()) continue;
int val=de[j].front().first+a[i]; // jia shang zhe ge shu
while(!de[j+].empty() && de[j+].back().first <=val ) de[j+].pop_back();
de[j+].push_back({val,i}); // di i ge wei zhi j+1 ge shu he zui da
if(j+==x&&i+k>n)
{
ans=max(val,ans);
}
}
}
cout<<ans<<endl; }

看的懂的代码