http://www.lydsy.com/JudgeOnline/problem.php?id=2017

这题太神了,我想了一个中午啊

原来是看错题一直没理解题解说的,一直以为题解是错的QAQ

“开始玩游戏时,第一个玩家可以从堆顶拿走一枚或两枚硬币”

果然还是太弱

我们发现,每一个阶段都由上一个玩家决定的,即别人怎么拿限制了我怎么拿,那么

设状态为f(i, j)表示剩余i个硬币,上次拿了j个硬币,注意,是上一次!

f(i, j)=max{sum(1, i)-f(i-k, k)} 1<=k<=2*j

这点可以参照前边一题的dp博弈

sum(1, i)包含了2重意思,即sum(1, i-k), sum(i-k+1, i),前者是之前局面的和,后者是玩家所得的价值

而f(i-k, k)的意思就是根据上一次所拿硬币j限制了我这次拿硬币k,而这个状态就表示我这次拿了k个之后还剩与i-k个,而且是从我这个状态k个限制了它所拿硬币。

然后注意读入是倒序即可

但是这样做状态是n^2,转移n,显然2000的数据tle。

那么我们要优化

(以下优化转自http://hi.baidu.com/tankche1/item/dda6af9b68f301c5b7253190

我们来看看f(10,1)的情况。

在这里,我们发现f(8,2)和f(8,1)的区别就是比其多了2条路,所以我们完全能想到以下方法。

将 除了自己特有的两条路保留后,另两条路舍去,直接连到f(8,1)的最优解上,这样就能将时间复杂度优化为O(n^2),这样的话,我们的状态转移方程可 以写为f(x,y)=Max{ f(x,y-1),sum[x]-Min{f(x-(2*y-1),2*y-1),f(x-2*y,2*y)} }

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << #x << " = " << x << endl
#define printarr(a, n, m) rep(aaa, n) { rep(bbb, m) cout << a[aaa][bbb]; cout << endl; }
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
inline const int max(const int &a, const int &b) { return a>b?a:b; }
inline const int min(const int &a, const int &b) { return a<b?a:b; } const int N=2005;
int f[N][N], n, a[N], sum[N];
int main() {
read(n);
for3(i, n, 1) read(a[i]);
for1(i, 1, n) sum[i]=sum[i-1]+a[i];
for1(i, 1, n)
for1(j, 1, n) {
f[i][j]=f[i][j-1];
if(i>=(j<<1))
f[i][j]=max(f[i][j], sum[i]-f[i-(j<<1)][(j<<1)]);
if(i-((j<<1)-1)>=0)
f[i][j]=max(f[i][j], sum[i]-f[i-((j<<1)-1)][(j<<1)-1]);
}
print(f[n][1]);
return 0;
}

Description

农 夫约翰的奶牛喜欢玩硬币游戏,因此他发明了一种称为“Xoinc”的两人硬币游戏。 初始时,一个有N(5 <= N <= 2,000)枚硬币的堆栈放在地上,从堆顶数起的第I枚硬币的币值为C_i (1 <= C_i <= 100,000)。 开始玩游戏时,第一个玩家可以从堆顶拿走一枚或两枚硬币。如果第一个玩家只拿走堆顶的一枚硬币,那么第二个玩家可以拿走随后的一枚或两枚硬币。如果第一个 玩家拿走两枚硬币,则第二个玩家可以拿走1,2,3,或4枚硬币。在每一轮中,当前的玩家至少拿走一枚硬币,至多拿走对手上一次所拿硬币数量的两倍。当没 有硬币可拿时,游戏结束。 两个玩家都希望拿到最多钱数的硬币。请问,当游戏结束时,第一个玩家最多能拿多少钱呢?

Input

第1行:1个整数N

第2..N+1行:第i+1行包含1个整数C_i

Output

第1行:1个整数表示第1个玩家能拿走的最大钱数。

Sample Input

5
1
3
1
7
2

Sample Output

9

HINT

样例说明:第1个玩家先取走第1枚,第2个玩家取第2枚;第1个取走第3,4两枚,第2个玩家取走最后1枚。

Source

【BZOJ】2017: [Usaco2009 Nov]硬币游戏(dp+神题+博弈论)的更多相关文章

  1. bzoj 2017 [Usaco2009 Nov]硬币游戏 动态规划

    [Usaco2009 Nov]硬币游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 431  Solved: 240[Submit][Status] ...

  2. 【题解】Luogu p2964 BZOJ 2017[Usaco2009 Nov]硬币游戏

    题目描述 Farmer John's cows like to play coin games so FJ has invented with a new two-player coin game c ...

  3. bzoj 2017: [Usaco2009 Nov]硬币游戏【dp】

    废了废了,一个小dp都想不出来 把c数组倒序一下,变成1在最下,设f[i][j]为某一人取完j个之后还剩1~i的硬币,转移的话应该是f[i][j]=max(s[i]-f[i-k][k]),就是1~n的 ...

  4. [bzoj 2017] [Usaco2009 Nov]硬币游戏

    一个多月没更博客了..(期间明白了自己有多傻逼. 这种问题大概就倒着做... f[i][j]:表示考虑剩下的硬币i..n,且之前的人取了j个时,先手最多拿到的钱数.aft[i]:表示硬币i..n的总钱 ...

  5. BZOJ_2017_[Usaco2009 Nov]硬币游戏_博弈论+DP

    BZOJ_2017_[Usaco2009 Nov]硬币游戏_博弈论+DP Description 农夫约翰的奶牛喜欢玩硬币游戏,因此他发明了一种称为“Xoinc”的两人硬币游戏. 初始时,一个有N(5 ...

  6. [BZOJ2017][Usaco2009 Nov]硬币游戏

    Description 农夫约翰的奶牛喜欢玩硬币游戏,因此他发明了一种称为“Xoinc”的两人硬币游戏. 初始时,一个有N(5 <= N <= 2,000)枚硬币的堆栈放在地上,从堆顶数起 ...

  7. [BZOJ2017][Usaco2009 Nov]硬币游戏(要复习系列)

    又是DP? 好吧,或者说是博弈论,但是我不会啊. 先搞个O(n^3)的记忆化搜索,然后瞎搞好像发现两个状态几乎一样? 竟然过了样例,然后竟然A了... #include<iostream> ...

  8. BZOJ 1770: [Usaco2009 Nov]lights 燈( 高斯消元 )

    高斯消元解xor方程组...暴搜自由元+最优性剪枝 -------------------------------------------------------------------------- ...

  9. BZOJ 1770: [Usaco2009 Nov]lights 燈

    Description 一个图,对一个点进行操作会改变这个点及其相邻的点的状态,问全部变成黑色至少需要几次.数据保证有解. Sol Meet in middle. 我一开始写个高斯消元,发现有两个点过 ...

随机推荐

  1. 正则表达式匹配a标签或div标签

    这里以a标签为例 a标签的href var a='<P><A href=\'~abc/ccg/ab.jpg\' width="3">文字</A> ...

  2. ORA-12519, TNS:no appropriate service handler found(数据库上当前的连接数目已经超过最大值)

    报错: ORA-12519, TNS:no appropriate service handler foundThe Connection descriptor used by the client ...

  3. JavaWeb 发送post请求的2种方式(form、json)

      JavaWeb 发送post请求的2种方式(form.json) CreationTime--2018年6月20日10点15分 Author:Marydon 前提:通过HttpClient来实现 ...

  4. RabbitMQ的应用场景以及基本原理介绍(转载)

    1.背景 RabbitMQ是一个由erlang开发的AMQP(Advanved Message Queue)的开源实现. 2.应用场景 2.1异步处理 场景说明:用户注册后,需要发注册邮件和注册短信, ...

  5. QT Unexpected CDB exit 问题的解决办法

    行QT进行debug时,提示 Unexpected CDB exit ,The CBD process terminated.. QtCreator 默认是没有调试器的,因此需要用户额外安装. win ...

  6. Chisel Tutorial(六)——port

    下面内容根据2015-7-10版的Chisel 2.2 Tutorial整理 port就是硬件单元对外的接口,须要指明方向(输入还是输出).一个port声明的样例例如以下: class Decoupl ...

  7. PHP 抽象类的使用

    //抽象类就是一个模版 abstract class db{ /* 参数:sql语句 返回值:索引的数组 */ abstract public function test($str); //没有方法体 ...

  8. Laravel自定义分页样式

    <?php namespace App\Http\Controllers; use DB; use App\Http\Controllers\Controller; class UserCont ...

  9. unity, 删除animationEvent

    当初给Player的一个animation加了个animationEvent,后来与之关联的响应函数删除了,于是导致报错: ‘Player’ AnimationEvent ‘idleHalfEvent ...

  10. 【转载】Oracle之内存结构(SGA、PGA)

    [转自]http://blog.itpub.net/25264937/viewspace-694917/ 一.内存结构 SGA(System Global Area):由所有服务进程和后台进程共享: ...