哇哇哇,这道傻逼线性dp居然卡了我这么就,还是看题解才改对的。
以后出来这种题目一定要会做了qwq。
首先这种线性dp第一维的值一般是枚举到第i个数组中的元素,第二维的值一般是一个约束,比如说背包的剩余容量,你已经用用去了多少次机会鸭等等等等。。。。
然后暴力枚举每一个量,每种量把第二维的约束条件都暴力刷表刷出来就好了。
然后就是状态转移方程,现在默认第一维是进行到第i个picture,第二维是以前要repost的picture总数。
dp i j = max(dp [ i-1 ~ i-k ][ j-1 ]+ a[ i ] ,dp[ i ][ j ])
注意这里默认到第i幅图片必须取走,这样可以考虑到所有情况。
暴力刷完表后,可以枚举 n-k+1到n中最大的元素作为答案因为最后取到的元素一定在这些元素之内。
注意这里的状态转移必须要让之前的状态是到达过的才能转移,所以dp数组的初值全部赋成-INF.
然后最开始能确定在没开始时i取0,j取0,dp的值是0.
开始暴力就可以求出每个状态的dp值了
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll INF=1e18; int a[210]; ll dp[210][210]; int main() { int n,k,x; scanf("%d%d%d",&n,&k,&x); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } for(int i=0;i<=n;i++) { for(int j=0;j<=x;j++) dp[i][j]=-INF; } dp[0][0]=0; for(int i=1;i<=n;i++) { for(int j=1;j<=x;j++) { for(int p=1;p<=k;p++) { if(i-p<0) break; if(dp[i-p][j-1]==-INF) continue; dp[i][j]=max(dp[i-p][j-1]+a[i],dp[i][j]); } } } ll res=-INF; for(int i=n-k+1;i<=n;i++) { for(int j=1;j<=x;j++) { res=max(dp[i][j],res); } } if(res!=-INF) printf("%lld\n",res); else printf("-1\n"); }