您的位置:首页 > 其它

UVA - 10891 Game of Sum 区间DP博弈

2014-11-20 23:15 363 查看
题目大意:有一系列的数字,两个人从这些数字中选择,可以从左选,也可以从右选,可以选1个以上,但是不能够左右两边同时选,选完数字后,求这两个人的差值是多少

解题思路:区间DP问题,设sum[i]为前i个数字的和,dp[i][j]为第i个数字到第j个数字的选择的最大和,则

dp[i][j] = sum[j] - sum[i-1] + min(dp[i+1][j],dp[i+2][j],...dp[i][j-2],dp[i][j-1]),min里面的是dp[i][j]的所有子区间,前面说了可以左右选择的,所以i+1到j的话就表示他选择了第i个,则dp[i+1][j]就是下一个人的最优选择了,那么sum[j]-sum[i-1] - MIN(区间内的最小值)就是这个人的最优选择了,右边的可以自己推,详细看代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF -0x3f3f3f3f
#define maxn 105
using namespace std;
int n,c[maxn],dp[maxn][maxn],sum[maxn];
int main() {
	while(scanf("%d",&n) != EOF && n) {	

		sum[0] = 0;	
		for(int i = 1; i <= n; i++) {
			scanf("%d",&c[i]);
			sum[i] = sum[i-1] + c[i];
			dp[i][i] = c[i];
		}

		for(int i = 1; i <= n; i++)
			for(int j = 1; j + i <= n; j++) {
				int k = j + i;
				int ans = INF;
				for(int l = j; l < k; l++) {
					int m = min(dp[j][l],dp[l+1][k]);//dp[j][l]表示从右往左选择了第l+1到第k个,dp[l+1][k]表示从左往右选择了第j个到第l个,l+1表示不会出现dp[j][k]的那种不选择的状况
					m = sum[k] - sum[j-1] - m;
					if(ans < m)
						ans = m;
				}

				if(ans < sum[k] - sum[j-1])
					ans = sum[k] - sum[j-1];
				dp[j][k] = ans;
			}
		printf("%d\n",dp[1]
*2-sum
);
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: