uva 10891(dp+博弈)

来源:互联网 发布:java中的同步和异步 编辑:程序博客网 时间:2024/04/29 11:28

题意:给出一个长度为n的数字序列,有两个玩家A、B,每次都是A先取数字,每个人每次都要取连续的1个或多个数字,不能同时从两端取数字,每个人都尽量用最优的方式来取,使自己取到的数字的总数最大。问最后A和B最大的差距是多少。

题解:因为每个人都以最优的方法取数字,无法确保自己取了最大值后就可以让自己达到最优,所以思路应该是每次选出当前选择区间内的最小值,然后这个值是给对方的,自己选的值就是当前区间和减去最小值,f[i][j]数组代表从i到j A选出的最优数字和,dp时先枚举选出区间长度,然后将区间内的值都计算然后选出从左开始和从右开始的最小值。

#include <stdio.h>#include <string.h>const int INF = 0x3f3f3f3f;const int N = 105;int n, s[N], sum[N];int f[N][N];int main() {while (scanf("%d", &n) && n) {memset(sum, 0, sizeof(sum));for (int i = 1; i <= n; i++) {scanf("%d", &s[i]);sum[i] = sum[i - 1] + s[i];}memset(f, 0, sizeof(f));for (int i = 1; i <= n; i++)f[i][i] = s[i];for (int i = 1; i <= n; i++) {for (int l = 1; i + l <= n; l++) {int r = i + l;int temp = sum[r] - sum[l - 1];int minn = INF;for (int k = l; k <= r; k++) {minn = minn < f[l][k] ? minn : f[l][k];minn = minn < f[k][r] ? minn : f[k][r];}f[l][r] = temp - minn;}}printf("%d\n", f[1][n] - (sum[n] - f[1][n]));}return 0;}


0 0