UVa 10891 (博弈+DP) Game of Sum】的更多相关文章

最开始的时候思路就想错了,就不说错误的思路了. 因为这n个数的总和是一定的,所以在取数的时候不是让自己尽可能拿的最多,而是让对方尽量取得最少. 记忆化搜索(时间复杂度O(n3)): d(i, j)表示原序列中第i个元素到第j个元素构成的子序列,先手取数能够得到的最大值. sum(i, j) 表示从第i个元素到第j个元素的和 因为要让对手获得最小的分数,所以状态转移方程为: d(i, j) = sum(i, j) - min{d(枚举所有可能剩给对手的序列), 0(0代表全部取完)} s数组保存a…
很明显带有博弈的味道.让A-B最大,由于双方都采用最佳策略,在博弈中有一个要求时,让一方的值尽量大.而且由于是序列,所以很容易想到状态dp[i][j],表示序列从i到j.结合博弈中的思想,表示初始状态i->j情况下,先手能获得的最大分数.后手能获得的就是sum[i][j]-dp[i][j].接下来枚举先手选取的是两端的哪一段即可. #include <iostream> #include <cstdio> #include <cstring> using name…
https://vjudge.net/problem/UVA-10891 给定一个序列x,A和B依次取数,规则是每次只能从头或者尾部取走若干个数,A和B采取的策略使得自己取出的数尽量和最大,A是先手,求最后A-B的得分. 令 f(i,j)表示对于[i,j]对应的序列,先手可以从中获得的最大得分,那么答案可以写为  f(i,j)-(sum(i,j)-f(i,j)),也就是 2*f(i,j)-sum(i,j) 下面讨论f(i,j)的写法,显然递归的形式更好表达一些,为了防止重复的计算使用记忆化搜索.…
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…
题意:给定一个长度为n的整数序列,两个人轮流从左端或者右端拿数,A先取,问最后A的得分-B的得分的结果. 析:dp[i][j] 表示序列 i~j 时先手得分的最大值,然后两种决策,要么从左端拿,要么从右端拿,肯定是拿的是最大的. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib…
刚看到这个题目不知道怎么个DP法,有点难想到 解法如下 设置dp[i][j]代表i到j这段子序列能获得的最大值,这样,枚举m=min(m,dp[i+1到j][j],dp[i][i到j-1]),m就代表了给另一个人的,就可求得就只能取到 dp[i][j]-sum(i,j)-m,这样,sum为该段序列总和,只需简单的数列前缀和即可求得sum,这样,只需枚举m值,不断向下进行记忆化搜索,即可求得终结果. #include <iostream> #include <cstdio> #inc…
在游戏的任何时刻剩余的都是1 - n中的一个连续子序列.所以可以用dp[i][j]表示在第i个数到第j个数中取数,先手的玩家得到的最大的分值.因为两个人都很聪明,所以等于自己和自己下.基本上每次就都是给对方留下一个烂棋局,所以上一个棋局应该是很优的,所以应该选择上一个棋局的最小值转移到当前棋局.所以得出了下面的方程dp[i][j] = min{dp[i + k][j](0 < k <= j - i)) dp[i][j - k](1 <= k <= j - i), 0}. 但是发现d…
问题来源:刘汝佳<算法竞赛入门经典--训练指南> P67 例题28: 问题描述:有一个长度为n的整数序列,两个游戏者A和B轮流取数,A先取,每次可以从左端或者右端取一个或多个数,但不能两端都取,所有数都被取完时游戏结束,然后统计每个人取走的所有数字之和作为得分,两人的策略都是使自己的得分尽可能高,并且都足够聪明,求A的得分减去B的得分的结果. 问题分析:1.设dp[i][j]表示从第i到第j的数的序列中,双方都采取最优策略的前提下,先手得分的最大值 2.若求dp[i][j],我们可以枚举从左边…
因为数的总和一定,所以用一个人得分越高,那么另一个人的得分越低. 用$dp[i][j]$表示从$[i, j]$开始游戏,先手能够取得的最高分. 转移通过枚举取的数的个数$k$来转移.因为你希望先手得分尽量高,所以另一个人的最高得分应尽量少. $dp[i][j] = sum[i][j] - \min \{dp[i + k][j],dp[i][j - k]\}$ 但是发现计算$dp[i + k][j],dp[i][j - k]$的最小值的地方很重复,所以用一个$f[i][j]$储存前者的最优值,$g…
题目链接:http://vjudge.net/problem/viewProblem.action?id=19461 思路:一类经典的博弈类区间dp,我们令dp[l][r]表示玩家A从区间[l, r]得到的最大值,于是就有dp[l][r] = sum[l][r] - min(dp[l + i][r], dp[l][r - i]) (i >= 1 && i + l <= r),最终我们要求的就是dp[1][n] - (sum[1][n] - dp[1][n]). #include…