最开始的时候思路就想错了,就不说错误的思路了。

因为这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中前i个元素的和,这样sum(i, j) = s[j] - s[i-1]

 #define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = + ;
int a[maxn], s[maxn], d[maxn][maxn], vis[maxn][maxn]; int dp(int i, int j)
{
if(vis[i][j])
return d[i][j];
vis[i][j] = ;
int m = ;
for(int k = i + ; k <= j; ++k)
m = min(m, dp(k, j));
for(int k = j - ; k >= i; --k)
m = min(m, dp(i, k));
d[i][j] = s[j] - s[i-] - m;
return d[i][j];
} int main(void)
{
#ifdef LOCAL
freopen("10891in.txt", "r", stdin);
#endif int n;
while(scanf("%d", &n) == && n)
{
s[] = ;
for(int i = ; i <= n; ++i)
{
scanf("%d", &a[i]);
s[i] = s[i-] + a[i];
}
memset(vis, , sizeof(vis));
printf("%d\n", *dp(, n) - s[n]);
}
return ;
}

代码君

递推(时间复杂度O(n2)):

令f(i, j) = min{d(i, j), d(i+1, j),,,d(j, j)}

g(i, j) = min{d(i, j), d(i, j-1),,,d(i, i)}

则状态转移方程可写成:

d(i, j) = min{f(i+1, j), g(i, j-1), 0}

f和g的递推为:

f(i, j) = min{d(i, j), f(i+1, j)}

g(i, j) = min{d(i, j), g(i, j-1)}

 //#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = + ;
int a[maxn], s[maxn], d[maxn][maxn], f[maxn][maxn], g[maxn][maxn]; int main(void)
{
#ifdef LOCAL
freopen("10891in.txt", "r", stdin);
#endif int n;
while(scanf("%d", &n) == && n)
{
s[] = ;
for(int i = ; i <= n; ++i)
{
scanf("%d", &a[i]);
s[i] = s[i-] + a[i];
}
for(int i = ; i <= n; ++i)//边界
d[i][i] = f[i][i] = g[i][i] = a[i];
for(int L = ; L < n; ++L)
for(int i = ; i + L <= n; ++i)
{
int j = i + L;
int m = ;
m = min(m, f[i+][j]);
m = min(m, g[i][j-]);
d[i][j] = s[j] - s[i-] - m;
//更新f和g
f[i][j] = min(d[i][j], f[i+][j]);
g[i][j] = min(d[i][j], g[i][j-]);
} printf("%d\n", *d[][n] - s[n]);
}
return ;
}

代码君

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

  1. UVA 10891 区间DP+博弈思想

    很明显带有博弈的味道.让A-B最大,由于双方都采用最佳策略,在博弈中有一个要求时,让一方的值尽量大.而且由于是序列,所以很容易想到状态dp[i][j],表示序列从i到j.结合博弈中的思想,表示初始状态 ...

  2. uva 10891 区间dp+记忆化搜索

    https://vjudge.net/problem/UVA-10891 给定一个序列x,A和B依次取数,规则是每次只能从头或者尾部取走若干个数,A和B采取的策略使得自己取出的数尽量和最大,A是先手, ...

  3. 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 ...

  4. UVa 10891 Game of Sum (DP)

    题意:给定一个长度为n的整数序列,两个人轮流从左端或者右端拿数,A先取,问最后A的得分-B的得分的结果. 析:dp[i][j] 表示序列 i~j 时先手得分的最大值,然后两种决策,要么从左端拿,要么从 ...

  5. UVA 10891 SUM游戏 DP

    刚看到这个题目不知道怎么个DP法,有点难想到 解法如下 设置dp[i][j]代表i到j这段子序列能获得的最大值,这样,枚举m=min(m,dp[i+1到j][j],dp[i][i到j-1]),m就代表 ...

  6. [题解]UVa 10891 Game of Sum

    在游戏的任何时刻剩余的都是1 - n中的一个连续子序列.所以可以用dp[i][j]表示在第i个数到第j个数中取数,先手的玩家得到的最大的分值.因为两个人都很聪明,所以等于自己和自己下.基本上每次就都是 ...

  7. 09_Sum游戏(UVa 10891 Game of Sum)

    问题来源:刘汝佳<算法竞赛入门经典--训练指南> P67 例题28: 问题描述:有一个长度为n的整数序列,两个游戏者A和B轮流取数,A先取,每次可以从左端或者右端取一个或多个数,但不能两端 ...

  8. UVa 10891 Game of Sum - 动态规划

    因为数的总和一定,所以用一个人得分越高,那么另一个人的得分越低. 用$dp[i][j]$表示从$[i, j]$开始游戏,先手能够取得的最高分. 转移通过枚举取的数的个数$k$来转移.因为你希望先手得分 ...

  9. hdu 4597 + uva 10891(一类区间dp)

    题目链接:http://vjudge.net/problem/viewProblem.action?id=19461 思路:一类经典的博弈类区间dp,我们令dp[l][r]表示玩家A从区间[l, r] ...

随机推荐

  1. 深入理解asp.net SessionState

    web Form 网页是基于HTTP的,它们没有状态, 这意味着它们不知道所有的请求是否来自同一台客户端计算机,网页是受到了破坏,以及是否得到了刷新,这样就可能造成信息的丢失. 于是, 状态管理就成了 ...

  2. Sqli-labs less 44

    Less-44 本关是基于盲注的,这里盲注主要是要没有报错信息,所以要采用盲注.这关与42关的区别就在于没有报错信息,同时,我们使用同样方式的payload: 登录 username:admin Pa ...

  3. 如何用 Parse 和 Swift 搭建一个像 Instagram 那样的应用?(3)

    [编者按]本篇文章作者是 Reinder de Vries,既是一名企业家,也是优秀的程序员,发表多篇应用程序的博客.本篇文章中,作者主要介绍了如何基于 Parse 特点,打造一款类似 Instagr ...

  4. 运行时修改TimerTask的执行周期

    java.util.TimerTask类的执行周期period变量的声明如下: /** * Period in milliseconds for repeating tasks. A positive ...

  5. HDU 1028 Ignatius and the Princess III (递归,dp)

    以下引用部分全都来自:http://blog.csdn.net/ice_crazy/article/details/7478802  Ice—Crazy的专栏 分析: HDU 1028 摘: 本题的意 ...

  6. VS2010中出现无法嵌入互操作类型

    针对word或excel操作时,出现VS2010中,无法嵌入互操作类型“……”,请改用适用的接口的解决方法 问了度娘,解决方法如出一辙:选中项目中引入的dll,鼠标右键,选择属性,把“嵌入互操作类型” ...

  7. java 静态构造函数

    在java中貌似是没有静态构造函数的. 不过用下面的方式同样可以实现效果. static { }//end 这是静态代码块

  8. POJ 1027 The Same Game(模拟)

    题目链接 题意 : 一个10×15的格子,有三种颜色的球,颜色相同且在同一片内的球叫做cluster(具体解释就是,两个球颜色相同且一个球可以通过上下左右到达另一个球,则这两个球属于同一个cluste ...

  9. WCF分布式开发步步为赢(2)自定义托管宿主WCF解决方案开发配置过程详解

    上一节<WCF分布式框架基础概念>我们介绍了WCF服务的概念和通信框架模型,并给出了基于自定义托管服务的WCF程序的实现代码.考虑到WCF分布式开发项目中关于托管宿主服务配置和客户端添加引 ...

  10. linux查找有用日志常用技巧

    对于高级测试人员来说.需要有快速定位问题的能力,而查看有效的日志就是其中有效的方法之一,然而服务器上的日志多如牛毛,如何快速从中找出所需信息非常重要,以下是我在工作中用到的查找日志的简单命令,希望对大 ...