背景

农民John的牛喜欢玩硬币,所以John就为它们发明了一个新的两人硬币游戏,叫做Xoinc。

描述

最初地面上有一堆n个硬币(5<=n<=2000),从上面数第i个硬币的价值为C_i(1<=C_i<=100000);

游戏开始后,A先取一枚或两枚硬币。如果A取了一枚,那么B可以继续取一枚或两枚;如果A取了两枚,那么B可以取一到四枚硬币。每次都只能从最上面取。每一次,当前取硬币的人都至少取一枚硬币,最多可以取他的对手上一次取硬币数目的两倍。当没有硬币可取的时候,游戏就结束了。

然后,他们就可以用得到的硬币向John买东西,当然,他们游戏的目的就是要尽可能使自己得到的硬币价值更大。现在你的任务是,求出在两个人都想得到更大价值的情况下,游戏结束后,第一个人最多能得到的硬币价值。

输入格式

第1行: 一个整数,N(5<=N<=2000)。

第2到n+1行: 第 i+1 行代表从上数第i枚硬币的价值。

输出格式

一行:一个数字,第一个人能得到的最大价值

测试样例1

输入






2

输出

9

备注

usaco nov09 Ag 
translated by pricez

思路集合

解题思路
首先明确这是一题DP题目
那么不难发现几个必须枚举的状态
1、对方在上一轮取了几个(这个直接影响我方这回合取的数目)
2、当前还剩多少个可以取
3、我方这回合取了多少个
接着
假设上回合对方拿走了J个后还剩I个可供我们这回合拿取,那么可以推出我们能拿的硬币数的范围在1~2*J之间则可以列出
F[I,J]:=MAX(SUM[I]-F[I-K,K]);(1<=K<=2*J)
其中SUM[I]表示剩下的I个硬币的总面值
K表示我当前这回合拿了多少个
因为双方都是最优的取法来取
所以F[I-K,K]表示的就是对手在我拿走K个硬币还剩下I-K个硬币的情况他最多能取的面值大小
因而SUM[I]-F[I-K,K]表示的意义就是我在剩下的硬币中能取得的最多的面值大小
初始状态是F[0,1~N]=0;
末状态是F[N,1]

理解了上面的方程后
可以看出方程的时间复杂度就是O(N^3)显然会超时
这时候就需要优化
我们观察
F[I,J]的方程与F[I,J-1]的方程
可以发现
F[I,J-1]所枚举的所有状态在F[I,J]时又枚举了一遍,明显这是多余的
可以看出F[I,J]比F[I,J-1]多枚举的只有SUM[I]-F[I-(2*J-1),2*J-1]和SUM[I]-F[I-2*J,2*J]两项
所以方程可以改写成
F[I,J]:=MAX(F[I,J-1],MAX(SUM[I]-F[I-(2*J-1),2*J-1],SUM[I]-F[I-2*J,2*J]));
这样就优化到O(N^2)了
基本调试清楚下就可以AC了
---------------------
其实不需如上优化
第一个方程+单调队列足以AC

 
转载:

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

设状态为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。

那么我们要优化

我们来看看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<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int N,a[],f[][],sum[];
int main(){
// freopen("01.txt","r",stdin);
scanf("%d",&N);
for(int i=N;i>;i--)
scanf("%d",&a[i]);
for(int i=;i<=N;i++)
sum[i]=sum[i-]+a[i]; for(int i=;i<=N;i++)
for(int j=;j<=N;j++){
f[i][j]=f[i][j-];//自己特有的两条路保留,直接连到f(i,j-1)的最优解上
if(i-(j<<)>=)
f[i][j]=max(f[i][j],sum[i]-f[i-(j<<)][j<<]);
if(i-((j<<)-)>=)
f[i][j]=max(f[i][j],sum[i]-f[i-((j<<)-)][(j<<)-]);
}
printf("%d\n",f[N][]);
return ;
}

TYVJ P1075 硬币游戏 Label:dp的更多相关文章

  1. tyvj P1075 - 硬币游戏 博弈DP

    P1075 - 硬币游戏 From price    Normal (OI)总时限:10s    内存限制:128MB    代码长度限制:64KB 背景 Background 农民John的牛喜欢玩 ...

  2. 【BZOJ】2017: [Usaco2009 Nov]硬币游戏(dp+神题+博弈论)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2017 这题太神了,我想了一个中午啊 原来是看错题一直没理解题解说的,一直以为题解是错的QAQ “开始 ...

  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 4820 [Sdoi2017]硬币游戏 ——期望DP 高斯消元

    做法太神了,理解不了. 自己想到的是建出AC自动机然后建出矩阵然后求逆计算,感觉可以过$40%$ 用一个状态$N$表示任意一个位置没有匹配成功的概率和. 每种匹配不成功的情况都是等价的. 然后我们强制 ...

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

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

  6. 【BZOJ4820】[Sdoi2017]硬币游戏 AC自动机+概率DP+高斯消元

    [BZOJ4820][Sdoi2017]硬币游戏 Description 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数多谁胜利.大家纷纷觉得这个游戏非常符合同学们的特色,但只是扔硬 ...

  7. 4820: [Sdoi2017]硬币游戏

    4820: [Sdoi2017]硬币游戏 链接 分析: 期望dp+高斯消元. 首先可以建出AC自动机,Xi表示经过节点i的期望次数,然后高斯消元,这样点的个数太多,复杂度太大.但是AC自动机上末尾节点 ...

  8. [BZOJ4820]硬币游戏 KMP+高斯消元

    4820: [Sdoi2017]硬币游戏 Time Limit: 10 Sec  Memory Limit: 128 MB Description 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的 ...

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

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

随机推荐

  1. 暑假热身 B. 下载测速

    最近,nono终于结束了每年一次的为期12个月的冬眠,醒来的第一件事就是——看电影!!nono发现最近一年出现了各种很好很强大的电影,例如这个.这个.还有这个. 于是nono直接把这些电影全部扔进了下 ...

  2. RAID阵列的初始化与管理

    如果我们创建RAID阵列的目的是新部署一台服务器,我们建议所有新创建的RAID阵列都应该做初始化操作,这样,硬盘上原有的用户数据将被清除,以便进行后续的系统,软件安装. 转自: http://zh.c ...

  3. 为eclipse设置好看的代码主题

    eclipse的默认代码背景是白色,上个文章简单说了字体设置,这边主要介绍代码高亮的主题设置,打造更酷的编程界面.网上有文章说可以在设置里面逐一设置,但是比较麻烦,可以去网上下载现成的主题包,网址为: ...

  4. java文件上传路径缺少\的解决办法

    今天做一个文件上传,取路径,然后读取文件的时候,发现存储到MySQL的路径是这样的:

  5. PageBean分页组件

    Page.java package org.guangsoft.bean; import java.util.List; public class Page { private int current ...

  6. July 30th, Week 31st Saturday, 2016

    No matter how far you may fly, never forget where you come from. 无论你能飞多远,都别忘了你来自何方. No matter how fa ...

  7. Java中ArrayList的自我实现

    对于ArrayList相比大家都很熟悉,它是java中最常用的集合之一.下面就给出它的自我实现的java代码. 需要说明的一点是,它是基于数组创建的.所以它在内存中是顺序存储,对于查找十分的方便. p ...

  8. 学习配置vsftp 进行ftp文件的传输

    一. FTP 说明 linux 系统下常用的FTP 是vsftp, 即Very Security File Transfer Protocol. 还有一个是proftp(Profession ftp) ...

  9. index index.html index.htm index.php

    server { listen 80; server_name localhost; index index.html index.htm index.php;#前后顺序有关系,越在前优先级别越高 r ...

  10. display : -webkit-box-inline 的理解

    发现: 最近在做移动端的东西,说起移动端弹性盒子布局真是无往不利,用起来特别爽,我也是偶尔间发现的这个属性并且它的用法,在网上基本查不到这个属性的资料(个人看法).如果没有听说过(display:bo ...