哇哇哇,这道傻逼线性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");
}