cf codeforces Round #521(Div3) F1. Pictures with Kittens (easy version)线性dp,简单dp

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

  

原文地址:https://www.cnblogs.com/lishengkangshidatiancai/p/9985189.html