[动态规划] Sum游戏 ( Game of Sum, Uva 10891 )

抓住状态转移方程即可   :  从子序列 i j 中取最大 =  i + 从子序列i+1,j中取最大        或         j +  从子序列i,j-1中取最大

#include <algorithm>
#include <cstring>
#include <cstdio>

using namespace std;

const int maxn = 100+10;
int S[maxn], A[maxn], d[maxn][maxn], vis[maxn][maxn], n;

int dp(int i, int j){
	if (vis[i][j]) return d[i][j];
	vis[i][j] = 1;

	if (i == j) {
		d[i][j] = A[i];
		return d[i][j];
	}

	d[i][j] = max(A[i] + S[i+1,j] - dp(i + 1,j), A[j] + S[i,j - 1] - dp(i,j - 1));
	return d[i][j];
}

int main(){
	while (scanf("%d", &n) && n){
		S[0] = 0;
		for (int i = 1; i <= n;i++)
		{
			scanf("%d", &A[i]);
			S[i] = S[i - 1] + A[i];
		}
		memset(vis, 0, sizeof(vis));
		printf("%d\n", 2*dp(1, n)-S[n]);
	}
	return 0;
}
时间: 2024-10-16 05:37:48

[动态规划] Sum游戏 ( Game of Sum, Uva 10891 )的相关文章

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)

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 ca

UVa 10891 (博弈+DP) Game of Sum

最开始的时候思路就想错了,就不说错误的思路了. 因为这n个数的总和是一定的,所以在取数的时候不是让自己尽可能拿的最多,而是让对方尽量取得最少. 记忆化搜索: d(i, j)表示原序列中第i个元素到第j个元素构成的子序列,先手取数能够得到的最大值. sum(i, j) 表示从第i个元素到第j个元素的和 因为要让对手获得最小的分数,所以状态转移方程为: d(i, j) = sum(i, j) - min{d(枚举所有可能剩给对手的序列), 0(0代表全部取完)} s数组保存a中前i个元素的和,这样s

js中sum(2)(3)(4)返回9和sum(2,3)和sum(2)(3)都返回5并要求扩展性

网上有很多关于sum(1)(2)(3),sum(1,2,3)之类的面试题要求输出相同的结果6并要求可以满足扩展,即有多个参数时也能符合题设的要求,所以自己写了部分例子可以大概满足这些面试题的要求 <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Document</title></head><

UVa 10891 Sum游戏

https://vjudge.net/problem/UVA-10891 题意: 有一个长度为n的整数序列,两个游戏者A和B轮流取数,A先取.每次玩家只能从左端或者右端取任意数量个数,但不能两端都取.所有数都被取走后游戏结束,然后统计每个人取走的所有数之和,作为各自的得分.两个人采取的策略都是让自己的得分尽量高,并且两个人都足够聪明,求A的得分减去B的得分后的结果. 思路: 不管是轮到谁取数,都是在一个序列中从左边或右边开始取最大值. 那么我们就令d[i][j]表示先手在[i~j]序列中所能取到

uva 10891 sum游戏(区间dp)

 给定n个数字,A和B可以从这串数字的两端任意选数字,一次只能从一端选取.并且A B都尽力使自己选择的结果为最大的,可以理解成A B每一步走的都是最优的.如果A先选择,则A B差值最大是多少. 思路:用d[i][j]表示当前选手先手走能获得的最大总分数,由于总的分数是一定的,那么状态转移方程为 d[i][j] = sum(i, j) - min( minleft(i+1, j), minright(i, j-1), 0) 其中minleft(i, j)表示min(d[i][j], d[i+1

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)

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

UVA 10891——Game of Sum

题目大意: 有n个数字排成一条直线,然后有两个小伙伴来玩游戏, 每个小伙伴每次可以从两端(左或右)中的任意一端取走一个或若干个数(获得价值为取走数之和), 但是他取走的方式一定要让他在游戏结束时价值尽量的高,最头疼的是两个小伙伴都很聪明,所以每一轮两人都将按照对自己最有利的方法去取数字,请你算一下在游戏结束时,先取数的人价值与后取数人价值之差(不要求绝对值). 有一个比这道题简单一点的题,是两边只能一个一个地取,做法如下: dp[i][j]表示i到j取到的最优值,用dp[i+1][j]或dp[i