zoukankan      html  css  js  c++  java
  • 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
    ");
    }
    

      

  • 相关阅读:
    MFC的序列化的一点研究.
    一次LoadRunner的CPC考试经历
    LAMP架构上(一)
    文件和目录管理
    如何在Linux上清理内存缓存、缓冲与交换空间
    Linux Shell基础(下)
    防火墙(上)
    LAMP架构(三)
    LNMP(二)
    LNMP(一)
  • 原文地址:https://www.cnblogs.com/lishengkangshidatiancai/p/9985189.html
Copyright © 2011-2022 走看看