LINK : coin game

这道题 超级经典去年这个时候我就看过题目了 但时至今日还不会/cy 觉得在做比赛的题目的时候少写省选的题目 多做水题多做不难也不简单的题目就好了。

由于我是真的不会博弈上dp(其实我博弈都不太会...故写这道题的时候没有过多的思考只是草草想了一波状态就直接看题解了发现状态都列错了。

当我 理解题解中的做法感觉还不是特别的自然故写一篇题解来印证自己的理解。

这里我写上最初始的思路吧 题目中想让我们两个玩家都选择最优的情况下 第一个玩家最多能获得多少的钱。看起来是一个博弈但是题目中有限制条件前一个玩家取了j个硬币的话后一个玩家最多取2*j个硬币。

那如何进行这个过程的呢 我们很难去博弈吧因为没有必胜点和必败点这个东西 不论胜败且每次决策紧扣下一次的决策 搜索复杂度超级高。

开始我也不知道应该选什么取得最优 如果我知道后续的状态 我们从起手的状态转移到最优后续的状态就好了 可是我们并不知道后续的状态?考虑先把后面的东西求出来转移到前面的比较好。

因为结束之后的状态我们是知道的选完了最后的状态显然是0 就从这个状态转移好了那么就有了状态 f[i]表示剩下i个硬币此时选择的最优状态首先解决的一个问题是由于两个人 都是选取最优的方法 故状态转移显然是一样的我们只要每次转移的时候从对方最优状态之中选择一个对自己最优的状态就好了 故转移到f[n] 由于第一个玩家先选 f[n] 就是我们的答案了 f[i]=max{sum[i]-f[k];}有了这个状态 相信此时对于两个人拥有同一个状态没有什么疑问了吧两个人都是选取最优的方法显然其实对方也是f数组的含义这样就计算好了f当前这个人如果选的话的最优解 显然我们还需要知道选择了多少个方便转移 那么状态空间到此就非常的完善了 f[i][j]表示剩下i个硬币上一次选了j个硬币的最优解 那么显然了状态转移 f[i][j]=max{sum[i]-f[i-k][k]} 其中k属于 1~2*j 然后 答案自然就是f[n][1]了。

非常的自然 不是么 我觉得难度还是有的 这值得我慢慢的推敲... 相信状态是我唯一的选择的。

//#include<bits/stdc++.h>
#include<iostream>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<cctype>
#include<utility>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<deque>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<iomanip>
#include<stack>
#include<string>
#include<cstring>
#define INF 2000000000
#define ll long long
#define db double
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)>(y)?(y):(x))
#define mp(x,y) make_pair(x,y)
using namespace std;
char buf[<<],*fs,*ft;
inline char getc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,,<<,stdin),fs==ft))?:*fs++;
}
inline int read()
{
int x=,f=;char ch=getc();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getc();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getc();}
return x*f;
}
const int MAXN=;
int n;
int a[MAXN],sum[MAXN];
int f[MAXN][MAXN];//f[i][j]表示 现在剩下1~i枚金币且上次取了j次当前第一个玩家能取到的最多钱数
int main()
{
//freopen("1.in","r",stdin);
n=read();
for(int i=n;i>=;--i)a[i]=read();
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-];
int w=(j<<)-;
if(w<=i)f[i][j]=max(f[i][j],sum[i]-f[i-w][w]);
++w;if(w<=i)f[i][j]=max(f[i][j],sum[i]-f[i-w][w]);
}
printf("%d\n",f[n][]);
return ;
}

[USACO09NOV]硬币的游戏 博弈 dp的更多相关文章

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

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

  2. [luogu2964][USACO09NOV][硬币的游戏A Coin Game] (博弈+动态规划)

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

  3. P2964 [USACO09NOV]硬币的游戏A Coin Game (DP)

    题意:n颗硬币 两个人从前往后按顺序拿 如果上一个人拿了i颗 那么下一个可以拿1-2*i颗 问先手能获得的最大收益 题解:比较典型的最大最小最大最小..DP了 但是暴力做的话是n^3 所以就体现出了这 ...

  4. 洛谷P2964 [USACO09NOV]硬币的游戏A Coin Game

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

  5. 计蒜客 取数游戏 博弈+dp

    题目链接 取数游戏 思路:dp(x, y)表示先手在区间[x, y]能取得的最大分数.当先手取完,就轮到后手去,后手一定会选择当前能令他得到最大分数的策略,其实当先手在[x, y]区间两端取走一个数, ...

  6. [USACO09NOV]硬币的游戏A Coin Game

    https://daniu.luogu.org/problemnew/show/P2964 dp[i][j] 表示桌面上还剩i枚硬币时,上一次取走了j个的最大得分 枚举这一次要拿k个,转移到dp[i- ...

  7. LUOGU P2964 [USACO09NOV]硬币的游戏A Coin Game

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

  8. 【P2964】硬币的游戏(DP+前缀和)

    一道DP,思维难度真是不小. 首先对于这个题的数据,我们可以发现差不多可以支持n^2logn,但是貌似也不会有这种复杂度的线性DP(至少这个题看上去不是这样).所以我们考虑N^2做法.因为求得是价值和 ...

  9. [LUOGU2964] [USACO09NOV]硬币的游戏A Coin Game

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

随机推荐

  1. directive 实例讲解

    http://my.oschina.net/ilivebox/blog/289670 gulp-nodemon http://www.zhihu.com/question/32123388?sort= ...

  2. P3295 萌萌哒 题解

    题目 一个长度为n的大数,用\(S_1,S_2,S_3...S_n\)表示,其中\(S_i\)表示数的第\(i\)位,\(S_1\)是数的最高位,告诉你一些限制条件,每个条 件表示为四个数,\(l_1 ...

  3. 3.第一个scrapy项目

    第一个scrapy项目 1. 创建scrapy项目 1.1 创建项目三剑客 这里的三剑客指的是:创建项目以及运行项目的三条命令 1.1.1 创建项目 scrapy stratproject 项目名称 ...

  4. 一文梳理Web存储,从cookie,WebStorage到IndexedDB

    前言 HTTP是无状态的协议,网络早期最大的问题之一是如何管理状态.服务器无法知道两个请求是否来自同一个浏览器.cookie应运而生,开始出现在各大网站,然而随着前端应用复杂度的提高,Cookie 也 ...

  5. Disruptor 高性能并发框架二次封装

    Disruptor是一款java高性能无锁并发处理框架.和JDK中的BlockingQueue有相似处,但是它的处理速度非常快!!!号称“一个线程一秒钟可以处理600W个订单”(反正渣渣电脑是没体会到 ...

  6. java 面向对象(一):类与对象

    1.面向对象学习的三条主线: * 1.Java类及类的成员:属性.方法.构造器:代码块.内部类 * * 2.面向对象的大特征:封装性.继承性.多态性.(抽象性) * * 3.其它关键字:this.su ...

  7. Django之Model、Form、ModelForm区别

    本节内容: 1:Model               https://www.cnblogs.com/shuai1991/p/10844662.html 2:Form                 ...

  8. Python网络编程02 /基于TCP、UDP协议的socket简单的通信、字符串转bytes类型

    Python网络编程02 /基于TCP.UDP协议的socket简单的通信.字符串转bytes类型 目录 Python网络编程02 /基于TCP.UDP协议的socket简单的通信.字符串转bytes ...

  9. Ethical Hacking - GAINING ACCESS(2)

    Server Side Attacks - INFORMATION GATHERING Need an IP address. Very simple if target is on the same ...

  10. 可能这是Redis可视化工具最全的横向评测

    1 命令行 不知道大家在日常操作redis时用什么可视化工具呢? 以前总觉得没有什么太好的可视化工具,于是问了一个业内朋友.对方回:你还用可视化工具?直接命令行呀,redis提供了这么多命令,操作起来 ...