UVa 10891 Game of Sum (区间DP&博弈)

来源:互联网 发布:淘宝lol代练可靠吗 编辑:程序博客网 时间:2024/05/01 12:05

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=114&page=show_problem&problem=1832


思路:

for (int i = 1; i <= b - a; i++)ans = max(ans, sum[b] - sum[a] - min(f(a + i, b), f(a, b - i)));return dp[a][b] = ans;
上述代码的dp[a][b]存储的是当数字剩为a~b段时,某人(可以是A,也可以是B)所能取数字的最佳和值,

sum[i]用前缀数组记录数字和值,

那么,作为一方,你能取的最大值就是这段总和减去对方所能取的最小值。


完整代码:

/*0.069s*/#include<bits/stdc++.h>using namespace std;const int N = 105;int n, dp[N][N], num[N], sum[N];bool vis[N][N];int f(int a, int b){if (a >= b) return 0;if (vis[a][b]) return dp[a][b];vis[a][b] = true;int ans = -INT_MAX, len = b - a;for (int i = 1; i <= len; i++)ans = max(ans, sum[b] - sum[a] - min(f(a + i, b), f(a, b - i)));return dp[a][b] = ans;}int main(){while (scanf("%d", &n), n){memset(dp, 0, sizeof(dp));memset(vis, 0, sizeof(vis));for (int i = 1; i <= n; i++){scanf("%d", &num[i]);sum[i] = sum[i - 1] + num[i];///前缀数组}printf("%d\n", f(0, n) * 2 - sum[n]);}return 0;}

0 0
原创粉丝点击