uva 10891 Game of Sum (DP)

uva 10891 Game of Sum (DP)

This is a two player game. Initially there are n integer numbers in an array and players
A and B get chance to take them alternatively. Each player can take one or more numbers from the left or right end of the array but cannot take from both ends at a time. He can take as many consecutive numbers as he wants during
his time. The game ends when all numbers are taken from the array by the players. The point of each player is calculated by the summation of the numbers, which he has taken. Each player tries to achieve more points from other. If both players play optimally
and player A starts the game then how much more point can player
A get than player B?

Input

The input consists of a number of cases. Each case starts with a line specifying the integer
n (0 < n ≤100), the number of elements in the array. After that,
n numbers are given for the game. Input is terminated by a line where
n=0.

Output

For each test case, print a number, which represents the maximum difference that the first player obtained after playing this game optimally.

Sample Input                                Output for Sample Input


4

4 -10 -20 7

4

1 2 3 4

0


7

10

题目大意:有n个石头排成一条排,然后有两个人来玩游戏, 每个人每次可以从两端(左或右)中的任意一端取走若干个石头(获得价值为取走石头之和), 但是他取走的方式一定要让他在游戏结束时价值尽量的高,两个人都很聪明,所以每一轮两人都将按照对自己最有利的方法去取数字,请你算一下在游戏结束时,先取数的人价值与后取数人价值之差。

解题思路:dp函数返回的是i到j玩家1可以取得最大值。

#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
using namespace std;
int S[105], A[105], d[105][105], vis[105][105], n;
int dp(int i, int j) { //dp函数返回的是i到j玩家1可以取得最大值
	if (vis[i][j]) return d[i][j];
	vis[i][j] = 1;
	int m = 0;
	for (int k = i + 1; k <= j; k++) {
		m = min(m, dp(k, j));
	}
	for (int k = i; k < j; k++) {
		m = min(m, dp(i, k));
	}
	d[i][j] = S[j] - S[i - 1] - m;
	return d[i][j];
}
int main() {
	while (scanf("%d", &n), n) {
		memset(vis, 0, sizeof(vis));
		S[0] = 0;
		for (int i = 1; i <= n; i++) {
			scanf("%d", &A[i]);
			S[i] = S[i - 1] + A[i];
		}
		printf("%d\n", 2 * dp(1, n) - S[n]); //dp(1, n) - (S[n] - dp(1, n))
	}
	return 0;
}
时间: 2024-08-06 07:56:45

uva 10891 Game of Sum (DP)的相关文章

Uva 10891 Game of Sum(区间博弈dp)

10891 - Game of Sum Time limit: 3.000 seconds This is a two player game. Initially there are n integer numbers in an array and players A and B get chance to take them alternatively. Each player can take one or more numbers from the left or right end

09_Sum游戏(UVa 10891 Game of Sum)

问题来源:刘汝佳<算法竞赛入门经典--训练指南> P67 例题28: 问题描述:有一个长度为n的整数序列,两个游戏者A和B轮流取数,A先取,每次可以从左端或者右端取一个或多个数,但不能两端都取,所有数都被取完时游戏结束,然后统计每个人取走的所有数字之和作为得分,两人的策略都是使自己的得分尽可能高,并且都足够聪明,求A的得分减去B的得分的结果. 问题分析:1.设dp[i][j]表示从第i到第j的数的序列中,双方都采取最优策略的前提下,先手得分的最大值 2.若求dp[i][j],我们可以枚举从左边

UVA 10891 Game of Sum(区间DP(记忆化搜索))

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1832 题目大意: 两个人在玩一个游戏: 给你一行n个数字,每次只能从左端或者右端取一个或多个数字. 每个人的分值就是他们各自取得的数字之和. 假设两人都足够聪明,问先手最多能比后手多多少分. 解题思路: 其实题目意思就是先手最多能得到多少分. 设dp[l][r]是取完[l,r]的

UVA - 10891 Game of Sum(记忆化搜索 dp)

#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; int a[100+10]; int dp[120][120]; int sum[120]; int vis[120][120]; int dfs(int f,int t) { int i,j,k; if(vis[f][t]==

UVA 10891 Game of Sum 区间dp

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19461 题目意思大致是给你一串数字,A,B两个人轮流从两端取一段数字并得到该串数字的和的点数,每个人都尽可能的多的点数,问A最多能比B多多少点. 区间dp,一开始打算分AB,但是发现太麻烦了,最后用dp(l,r)表示在区间l~r中先手能赢的的最多点数.假设A是区间(l,r)的先手的话,如果A选择了(l,k )// 或(k+1,r)的数字,那他的得分(l,r)的总分减去B在余

UVA 10891 Game of Sum(DP)

This is a two player game. Initially there are n integer numbers in an array and players A and B get chance to take them alternatively. Each player can take one or more numbers from the left or right end of the array but cannot take from both ends at

UVA - 10891 Game of Sum (区间dp)

题意:AB两人分别拿一列n个数字,只能从左端或右端拿,不能同时从两端拿,可拿一个或多个,问在两人尽可能多拿的情况下,A最多比B多拿多少. 分析: 1.枚举先手拿的分界线,要么从左端拿,要么从右端拿,比较得最优解. 2.dp(i, j)---在区间(i, j)中A最多比B多拿多少. 3.tmp -= dfs(i + 1, r);//A拿了区间(l, i),B在剩下区间里尽可能拿最优 tmp是A拿的,dfs(i + 1, r)是B比A多拿的,假设dfs(i + 1, r)=y-x,y是B拿的,x是A

UVA - 10891 —— Game of Sum

题目:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19461 这道题是一道很好的线性DP的题目,这种双头都可以选取的,可以运用带有头.尾位置信息的状态 dp[i][j] := 以第i位开头,第j位结尾的子问题的最优解 dp[i][j] = max(sum(i, i+k1) - dp[i+k1+1][j], sum(i, j-k2) - dp[i][j-k2-1])  (当 i <= j,注:i+k1 <= j &

UVA 10891 Game of Sum

题解: 这个题的题意挺误解人的. 每次选取的最优策略.我的理解每次从左开始.或从右开始.选取最大值(每个位置选取的最大值的位置是固定的).把剩下的序列给对方....但题意并不是这样 看了题解. 表示dp[ i ][ j ] 表示 区间 i j 先选得到的最大值. dp[ i ][ j ] = sum( j ) - sum( i - 1 ) - min( dp( i + 1, j ), dp( i + 2, j ), dp( i + 3, j )...dp( j ,j ), dp(  i , j