zoukankan      html  css  js  c++  java
  • HDU6199 gems gems gems (DP)

    题意:有n颗石子 两个人轮流拿 如果上一个人拿了x颗 这个人就可以拿x或x+1颗

       问先手能获得与后手的价值差最大是多少

    题解:看起来是博弈 其实是DP

       dp[i][j][0/1]表示当前该0/1拿 拿到第i颗上一个人拿了j个 转移就很裸了

       因为当前有两种操作拿x个和拿x+1个 要知道哪一个操作更好 需要知道后面的状态 所以就倒着DP

       因为爆内存就滚动了  对2^k取% = & 2^k - 1 感觉这样滚动会少个常数

    #include <bits/stdc++.h>
    using namespace std;
    
    int q[20005];
    int sum[20005];
    int dp[265][205][2];
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--)
        {
            sum[0] = 0;
            int n; scanf("%d", &n);
            for(int i = 1; i <= n; i++) scanf("%d", &q[i]), sum[i] = sum[i - 1] + q[i];
    
            memset(dp, 0, sizeof(dp));
            for(int i = n; i >= 1; i--)
            {
                for(int j = 1; j <= 200; j++)
                {
                    if(i + j == n + 1)
                    {
                        dp[i & 255][j][1] = sum[n] - sum[i - 1];
                        dp[i & 255][j][0] = sum[i - 1] - sum[n];
                        break;
                    }
    
                    dp[i & 255][j][1] = max(dp[(i + j) & 255][j][0], dp[(i + j + 1) & 255][j + 1][0] + q[i + j]) + sum[i + j - 1] - sum[i - 1];
                    dp[i & 255][j][0] = min(dp[(i + j) & 255][j][1], dp[(i + j + 1) & 255][j + 1][1] - q[i + j]) - sum[i + j - 1] + sum[i - 1];
                }
            }
            printf("%d
    ", dp[1][1][1]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    AD域渗透总结
    CTF
    ew做代理 进一步内网渗透
    CVE-2019-0708复现
    win 内网frp反弹到内网liunx
    Liunx反弹shell的几种方式
    sql到python正则
    PHP面向对象学习-属性 类常量 类的自动加载 构造函数和析构函数 访问控制(可见性)
    PHP反序列化学习
    PHP面向对象学习
  • 原文地址:https://www.cnblogs.com/lwqq3/p/10182196.html
Copyright © 2011-2022 走看看