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

因为这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. Tomcat自动启动脚本

    Tomcat自动启动脚本#!/bin/bash # chkconfig: 2345 10 90 # description: Starts and Stops the Tomcat daemon. T ...

  2. CentOS 6下安装nginx

    原文:http://yubosun.akhtm.com/tech/centos-nginx.htm 1 在nginx官方网站下载一个rpm包,下载地址是:http://nginx.org/en/dow ...

  3. 用 VIPER 构建 iOS 应用架构(2)

    [编者按]本篇文章由 Jeff Gilbert 和 Conrad Stoll 共同编写,通过构建一个基础示例应用,深入了解 VIPER,并从视图.交互器等多个部件理清 VIPER 的整体布局及思路.通 ...

  4. 字典树trie的学习与练习题

    博客详解: http://www.cnblogs.com/huangxincheng/archive/2012/11/25/2788268.html http://eriol.iteye.com/bl ...

  5. 构建iOS稳定应用架构时方案选择的思考,主要涉及工程结构,数据流思想和代码规范

    工程结构架构,减少耦合混乱以及防治需求大改造成结构重构,如何构建稳定可扩展可变换的工程结构的思考 我打算采用Information flow的方式自上而下,两大层分为基础层和展现层的结构.基础层分为多 ...

  6. Xcode 创建静态库和动态库

    1.linux中静态库和动态库区别: 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 静态库:这类库的名字一般是libxxx.a:利用静态函数库编译成的文件 ...

  7. Linux静态库和动态库

    Linux 工具 ❑ GCC: The GNU Compiler Collection, containing the GNU C compiler❑ G++: A C++ compiler, inc ...

  8. lintcode:删除链表中指定元素

    题目 删除链表中等于给定值val的所有节点. 样例 给出链表 1->2->3->3->4->5->3, 和 val = 3, 你需要返回删除3之后的链表:1-> ...

  9. libprotobuf ERROR

    google/protobuf/wire_format.cc:1059] Encountered string containing invalid UTF-8 data while parsing  ...

  10. ubuntu系统使用minicom终端操作说明

    http://blog.chinaunix.net/uid-22030783-id-3350834.html 在linux下,使用minicom作为串口终端工具,默认的串口设备是/dev/ttyS0, ...