Codeforces Round #380 Div.2 F - Financiers Game
Posted notnight
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #380 Div.2 F - Financiers Game相关的知识,希望对你有一定的参考价值。
这种两人博弈一般都可以用两个dp写, 一个dp描述第一个人的最优态, 第二个dp描述第二个人的最优态,难点在于优化空间。。。
我感觉这个空间开得有点玄学。。
dp[ op ][ l ] [ d ] [ k ] 表示到第op个人先手,在第任意轮的时候第一个人和第二个人取的个数只差不会超过180,所以用他们的差值开一维状态。
d = (l - 1) - (n - r), 只有区间 (l , n + d - l - 1)的情况下的最优值。
1 #include<bits/stdc++.h> 2 #define LL long long 3 #define mk make_pair 4 using namespace std; 5 6 const int N = 2e3 + 50; 7 const int inf = 0x3f3f3f3f; 8 int B = 95, n; 9 int dp[2][N][180][180], a[N]; 10 11 int dfs(int l, int r, int k, int op) { 12 int d = (l - 1) - (n - r); 13 int &ans = dp[op][l][B + d][k]; 14 if(ans != -1) return ans; 15 int ret; 16 if(op == 0) { 17 if(l + k - 1 == r) return dp[op][l][B + d][k] = a[r] - a[l - 1]; 18 else if(l + k - 1 > r) return dp[op][l][B + d][k] = 0; 19 20 int ret1 = dfs(l + k, r, k, op ^ 1) + a[l + k -1] - a[l - 1]; 21 int ret2 = dfs(l + k + 1, r, k + 1, op ^ 1) + a[l + k] - a[l - 1]; 22 ret = max(ret1, ret2); 23 } else { 24 if(l + k - 1 == r) return dp[op][l][B + d][k] = -a[r] + a[l - 1]; 25 else if(l + k - 1 > r) return dp[op][l][B + d][k] = 0; 26 27 int ret1 = dfs(l, r - k, k, op ^ 1) - a[r] + a[r - k]; 28 int ret2 = dfs(l, r - k - 1, k + 1, op ^ 1) - a[r] + a[r - k - 1]; 29 ret = min(ret1, ret2); 30 } 31 return dp[op][l][d + B][k] = ret; 32 } 33 int main() { 34 memset(dp, -1, sizeof(dp)); 35 scanf("%d", &n); 36 for(int i = 1; i <= n; i++) 37 scanf("%d", &a[i]), a[i] += a[i - 1]; 38 int ans = dfs(1, n, 1, 0); 39 printf("%d\n", ans); 40 return 0; 41 } 42 /* 43 */
以上是关于Codeforces Round #380 Div.2 F - Financiers Game的主要内容,如果未能解决你的问题,请参考以下文章
codeforces Codeforces Round #380 (Div. 1, Rated, Based on Technocup 2017 - Elimination Round 2)// 二分
Codeforces Round #380 Div.2 F - Financiers Game
Codeforces Round #380 (Div. 2) C. Road to Cinema 二分