HDU 6199 DP

来源:互联网 发布:淘宝创建店铺流程 编辑:程序博客网 时间:2024/06/05 21:02

简略题意:AB玩游戏,A先手。有n个数,第i个数的大小为v[i]。第一次能从左边取12个数,之后假如之前取了k个数,下次必须取kk+1个数。A想要他的值尽可能比对方大,而B想要他的值尽可能比对方小。两人轮流行动,问最终结果是多少。

Alice wants to maximize the difference while Bob wants to minimize it. 被题意杀了...怎么看都是A想最大化差值,B想最小化差值吧。

那正确理解题意之后就可以解题啦。
dp[i][j][k],代表前i个已经处理完,前一步拿了j个数字,当前是第k个人进行操作。
转移也很简单。
1. 若当前取了j个数字,dp[i][j][k]>dp[i+j][j][k1]+sum[i+j]sum[i]
2. 若当前取了j+1个数字,dp[i][j][k]>dp[i+j+1][j+1][k1]+sum[i+j+1]sum[i]sum代表前缀和。
此时我们发现我们只知道初始状态是什么,而末状态不定,因此需要逆推。
复杂度如何计算呢,考虑最坏情况,每次都取比上一次多的个数。
1+2+3+......+x=n>x(2n)
因此时间复杂度和空间复杂度都为O(n(n))。时间上问题不大,我们需要优化一下空间。
可以发现我们每次转移只需要用到不超过j+1个位置的数,因此需要滚动一下,就可以把空间优化到O(n)

#include <bits/stdc++.h>using namespace std;typedef long long LL;const int maxn = 22000;const int mod = 210;int t;int n;int sum[maxn];int dp[mod][mod][2];int val[maxn];void umax(int &x, int y) {    if(x < y) x = y;}void umin(int &x, int y) {    if(x > y) x = y;}int main() {    scanf("%d", &t);    while(t--) {        scanf("%d", &n);        sum[0] = 0;        for(int i = 1; i <= n; i++) scanf("%d", &val[i]), sum[i] = sum[i-1] + val[i];        memset(dp, 0, sizeof dp);        int limit = sqrt(2*n);        for(int i = n; i >= 0; i--) {            for(int j = 0; j <= limit; j++) {                for(int k = 0; k < 2; k++) {                    int v1 = sum[i+j] - sum[i];                    int v2 = sum[i+j+1] - sum[i];                    int p1 = i % mod, p2 = (i+j)%mod, p3 = (i+j+1)%mod;                    if(k == 0) {                        if(i + j <= n)                            dp[p1][j][k] = dp[p2][j][k^1] + v1;                        if(i + j + 1 <= n)                            umax(dp[p1][j][k], dp[p3][j+1][k^1] + v2);                    } else {                        if(i + j <= n)                            dp[p1][j][k] = dp[p2][j][k^1] - v1;                        if(i + j + 1 <= n)                            umin(dp[p1][j][k], dp[p3][j+1][k^1] - v2);                    }                }            }        }        cout<<dp[0][1][0]<<endl;    }    return 0;}
原创粉丝点击