zoukankan      html  css  js  c++  java
  • hdu 6199 dp

    题意:巨毒。。实际上就是A,B都希望自己得到的最多。前一个人拿k个,下一个人能拿k or k+1

    思路:倒着DP。。实际上两个人是同一种策略,那么其实一个dp数组就可以了。。从最后一步拿k个往回推,dp[i][j]表示取第i个时候拿走包含i的j个,转移方程dp[i][j]=sum[i+j-1]-sum[i-1]-max(dp[i+j][j],dp[i+j][j+1]) (PS,注意一下边界的合法性判断),转移的时候要减去上一步的最优解。。因为每一步对手都会选择最优策略。。

    PS。这个题卡空间。。。要么只开一个数组,要么循环滚动一下

    代码:

    #include<bits/stdc++.h>
    #define MEM(x) memset(x,0,sizeof(x))
    using namespace std;
    int dp[22000][205],n,sum[22010],v[22010];
    int main(){
    	int t;
    	scanf("%d", &t);
    	while (t--){
    		scanf("%d",&n);
            sum[0]=0;
            MEM(dp);MEM(sum);
            for(int i=1;i<=n;++i)scanf("%d",&v[i]),sum[i]=sum[i-1]+v[i];
            if(n==1){
                 printf("%d
    ",v[1]);
                 continue;
            }
            int lim = 200;
            for(int i=n;i>=1;--i){
                for(int j =1;j<=lim;++j){
                    if(i+j-1>n) break;
                    int sub=-2e9;
                    dp[i][j]=sum[i+j-1]-sum[i-1];
                    if(i+j+j-1<=n)sub=max(dp[i+j][j],sub);
                    if(i+j+j<=n)sub=max(dp[i+j][j+1],sub);
                    if(sub!=-2e9) dp[i][j]-=sub;
                }
            }
            printf("%d
    ", max(dp[1][1],dp[1][2]));
    	}
    	return 0;
    }
    



  • 相关阅读:
    Codeforces610b
    Codeforces597A
    Timus1014(贪心算法)
    一般贪心
    优先队列问题(此题来源哈尔滨理工大学VJ)
    POJ2551Dungeon Master
    LightOJ 1140: How Many Zeroes? (数位DP)
    HDU 2089:不要62(数位DP)
    HDU 4722:Good Numbers(数位DP)
    HDU 3709: Balanced Number (数位DP)
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/10672480.html
Copyright © 2011-2022 走看看