uva 10891 - Game of Sum(博弈,区间dp)
2013-07-31 13:28
453 查看
点击打开链接
题目大意:
有长度为n的正数序列,两个游戏者A 和B轮流取,A先取。每次玩家可以选择从序列左边或右边开始取一个或连续多个数字,问最终A最多可以比B大多少?
分析:
设f[l][r]表示对于区间[l,r]的序列,先取的人最多可以取的和。
那么,可以选择把[l,r]的所有数全部取光,或者只取一部分。
如果只取一部分,假设是[l,k]z这区间全部取,那么总共可以得到的和为sum[l,k]+(sum[k+1,r]-f[k+1][r])
所以状态转移为:
f[l][r] = sum[l][r]-min{ min{f[l][k], f[k+1][r]} }, l<=k<r
题目大意:
有长度为n的正数序列,两个游戏者A 和B轮流取,A先取。每次玩家可以选择从序列左边或右边开始取一个或连续多个数字,问最终A最多可以比B大多少?
分析:
设f[l][r]表示对于区间[l,r]的序列,先取的人最多可以取的和。
那么,可以选择把[l,r]的所有数全部取光,或者只取一部分。
如果只取一部分,假设是[l,k]z这区间全部取,那么总共可以得到的和为sum[l,k]+(sum[k+1,r]-f[k+1][r])
所以状态转移为:
f[l][r] = sum[l][r]-min{ min{f[l][k], f[k+1][r]} }, l<=k<r
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; typedef long long int64; const int INF = 0x3f3f3f3f; int n, arr[110], sum[110]; int f[110][110]; int main(){ sum[0] = 0; while(~scanf("%d", &n) && n){ for(int i=1; i<=n; ++i){ scanf("%d", &arr[i]); sum[i] = sum[i-1] + arr[i]; } memset(f, 0, sizeof(f)); for(int i=1; i<=n; ++i) f[i][i] = arr[i]; for(int len=2; len<=n; ++len){ for(int l=1; l+len-1<=n; ++l){ int r = l+len-1; int tot = sum[r] - sum[l-1]; f[l][r] = tot; // 把[l, r]全部取 for(int k=l; k<r; ++k){ f[l][r] = max(f[l][r], tot-min(f[l][k], f[k+1][r])); //选择取[l,k]或[k+1,r]的情况 } } } printf("%d\n", 2*f[1] -sum ); } return 0; }
相关文章推荐
- UVA 10891 Game of Sum(区间博弈dp)***
- UVa 10891 Game of Sum(博弈区间DP)
- uva_10891 - Game of Sum( 博弈区间DP )
- UVa 10891 Game of Sum (区间DP&博弈)
- Uva 10891 Game of Sum(区间博弈dp)
- UVa 10891 Game of Sum(经典博弈区间DP)
- uva10891 Game of Sum 博弈区间dp
- UVA 10891 Game of Sum(区间DP)
- UVA 10891 Game of Sum(区间DP)
- UVA 10891 Game of Sum(区间DP)
- UVA 10891 Game of Sum(dp博弈)
- UVA 10891 Game of Sum(区间DP)
- UVa UVA 10891 Game of Sum (区间DP)
- UVA 10891 Game of Sum(区间DP)
- Uva 10891 - Game of Sum ( 区间dp )
- UVA 10891 Game of Sum(区间DP)
- UVA 10891 Game of Sum(区间DP)
- UVA - 10891 Game of Sum(区间dp)
- UVA 10891 Game of Sum(区间DP)
- UVA 10891 Game of Sum(区间DP)