zoukankan      html  css  js  c++  java
  • HDU

    有n(2e4)个宝石
    两个人轮流从左侧取宝石,Alice先手,首轮取1个或2个宝石,
    如果上一轮取了k个宝石,则这一轮只能取k或k+1个宝石。
    一旦不能再取宝石就结束。
    双方都希望自己拿到的宝石数比对方尽可能多。
    问你,先手比后手多拿的最大宝石数。

    dp[s][k] 表示从已经拿了s个,这一次可以拿k个,也可以拿k+1个。

    那么dp[s][k] 表示 已经拿了s个,这一次可以拿k个或k+1个的最大差值。

    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int maxn = 20000 + 10;
    const int INF = 0x3f3f3f3f;
    
    int a[maxn], sum[maxn];
    int dp[maxn][212];
    int n;
    
    int DP(int s, int k) 
    {
        if(dp[s][k] != -INF) return dp[s][k];
        if (s+k <= n) dp[s][k] = max(dp[s][k], sum[s+k]-sum[s]-DP(s+k, k));
        if (s+k+1 <= n) dp[s][k] = max(dp[s][k], sum[s+k+1]-sum[s]-DP(s+k+1, k+1));
        if (dp[s][k] == -INF) dp[s][k] = 0;
        return dp[s][k];
    }
    
    void init()
    {
        memset(sum, 0, sizeof(sum));
        for (int i = 0; i < maxn; i++)
            for (int j = 0; j <= 200; j++)
                dp[i][j] = -INF;
    }
    
    int main()
    {
        int t;
        scanf("%d", &t);
        for (int ca = 1; ca <= t; ca++)
        {
            init();
            scanf("%d", &n);
            for (int i = 1; i <= n; i++)
                scanf("%d", &a[i]), sum[i] = sum[i-1] + a[i];
            printf("%d
    ", DP(0, 1));
        }
    }
  • 相关阅读:
    当算法提升到哲学层面—小议验证码识别
    2014总结
    [脚本无敌2]python获取cocos 2dx项目文件列表
    单幅图构建三维图
    [思考]画个圈圈诅咒你
    Mybatis2
    Mybatis1
    淘淘商城虚拟机启动命令
    Zookeeper集群搭建zookeeper01启动不成功解决方案
    Mybatis的xml文件的相关配置
  • 原文地址:https://www.cnblogs.com/ruthank/p/9559111.html
Copyright © 2011-2022 走看看