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中前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的更多相关文章
- UVA 10891 区间DP+博弈思想
很明显带有博弈的味道.让A-B最大,由于双方都采用最佳策略,在博弈中有一个要求时,让一方的值尽量大.而且由于是序列,所以很容易想到状态dp[i][j],表示序列从i到j.结合博弈中的思想,表示初始状态 ...
- uva 10891 区间dp+记忆化搜索
https://vjudge.net/problem/UVA-10891 给定一个序列x,A和B依次取数,规则是每次只能从头或者尾部取走若干个数,A和B采取的策略使得自己取出的数尽量和最大,A是先手, ...
- 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 ...
- UVa 10891 Game of Sum (DP)
题意:给定一个长度为n的整数序列,两个人轮流从左端或者右端拿数,A先取,问最后A的得分-B的得分的结果. 析:dp[i][j] 表示序列 i~j 时先手得分的最大值,然后两种决策,要么从左端拿,要么从 ...
- UVA 10891 SUM游戏 DP
刚看到这个题目不知道怎么个DP法,有点难想到 解法如下 设置dp[i][j]代表i到j这段子序列能获得的最大值,这样,枚举m=min(m,dp[i+1到j][j],dp[i][i到j-1]),m就代表 ...
- [题解]UVa 10891 Game of Sum
在游戏的任何时刻剩余的都是1 - n中的一个连续子序列.所以可以用dp[i][j]表示在第i个数到第j个数中取数,先手的玩家得到的最大的分值.因为两个人都很聪明,所以等于自己和自己下.基本上每次就都是 ...
- 09_Sum游戏(UVa 10891 Game of Sum)
问题来源:刘汝佳<算法竞赛入门经典--训练指南> P67 例题28: 问题描述:有一个长度为n的整数序列,两个游戏者A和B轮流取数,A先取,每次可以从左端或者右端取一个或多个数,但不能两端 ...
- UVa 10891 Game of Sum - 动态规划
因为数的总和一定,所以用一个人得分越高,那么另一个人的得分越低. 用$dp[i][j]$表示从$[i, j]$开始游戏,先手能够取得的最高分. 转移通过枚举取的数的个数$k$来转移.因为你希望先手得分 ...
- hdu 4597 + uva 10891(一类区间dp)
题目链接:http://vjudge.net/problem/viewProblem.action?id=19461 思路:一类经典的博弈类区间dp,我们令dp[l][r]表示玩家A从区间[l, r] ...
随机推荐
- Java正则表达式匹配例子
Java正则表达式匹配例子 package com.ibm.test; import java.util.regex.Matcher; import java.util.regex.Pattern; ...
- Ado.Net要知道的东西
什么是ADO.NET? ADO.NET就是一组类库,这组类库可以让我们通过程序的方式访问数据库,就像System.IO下的类用类操作文件一样,System.Data.这组类是用来操作数据库(不光是MS ...
- ASP 中调用函数关于Call使用注意的问题
Function TestFun(Tstr) TStr = "Fun2" End Function Sub TestSub(TStr) Tstr = "Sub2" ...
- VS2012简单的使用感受+插件推荐
VS2012简单的使用感受+插件推荐http://www.cnblogs.com/tangge/archive/2013/03/12/2955367.html
- 10个最佳的网站和App开发工具
这个世界充满了创新,开发的激情和决心是实现更高目标的关键因素.在网站开发中,毫无疑问,工具和可用的在线网页和 app 设计资源,发挥了重要的作用. 下面我们将带来一些网站和 app 的最佳工具. ...
- TCP非阻塞accept和非阻塞connect
http://blog.chinaunix.net/uid-20751538-id-238260.html 非阻塞accept 当一个已完成的连接准备好被accept的时候,select会把监 ...
- nodejs 操作mysql
这篇文章主要介绍了nodejs中操作mysql数据库示例,本文演示了如何在NodeJS中创建创建mysql连接.mysql数据库.插入数据.查询数据等功能,需要的朋友可以参考下 引言: 继前面的No ...
- QTableWidget使用简单,因为不再存在父节点的关系
虽然使用比较简单,但亲自过一遍还是有必要的,权当一个学习笔记吧,记录在此. #include "tablewidgetxxx.h" #include <QtGui/QAppl ...
- wordpress自定义栏目
开启自定义栏目:点击头顶的“显示选项”,勾选“自定义栏目” 然后编辑文章时,即可看见 实验: 定义名称为:play_url ,值为:http://www.xiami.com/widget/635357 ...
- SQL Server 使用日志传送
参考文献: http://msdn.microsoft.com/en-us/library/ms187103.aspx 概述 SQL Server 使用日志传送,您可以自动将“主服务器”实例上“主数据 ...