[USACO09NOV]硬币的游戏 博弈 dp
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的更多相关文章
- tyvj P1075 - 硬币游戏 博弈DP
P1075 - 硬币游戏 From price Normal (OI)总时限:10s 内存限制:128MB 代码长度限制:64KB 背景 Background 农民John的牛喜欢玩 ...
- [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 ...
- P2964 [USACO09NOV]硬币的游戏A Coin Game (DP)
题意:n颗硬币 两个人从前往后按顺序拿 如果上一个人拿了i颗 那么下一个可以拿1-2*i颗 问先手能获得的最大收益 题解:比较典型的最大最小最大最小..DP了 但是暴力做的话是n^3 所以就体现出了这 ...
- 洛谷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 ...
- 计蒜客 取数游戏 博弈+dp
题目链接 取数游戏 思路:dp(x, y)表示先手在区间[x, y]能取得的最大分数.当先手取完,就轮到后手去,后手一定会选择当前能令他得到最大分数的策略,其实当先手在[x, y]区间两端取走一个数, ...
- [USACO09NOV]硬币的游戏A Coin Game
https://daniu.luogu.org/problemnew/show/P2964 dp[i][j] 表示桌面上还剩i枚硬币时,上一次取走了j个的最大得分 枚举这一次要拿k个,转移到dp[i- ...
- 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 ...
- 【P2964】硬币的游戏(DP+前缀和)
一道DP,思维难度真是不小. 首先对于这个题的数据,我们可以发现差不多可以支持n^2logn,但是貌似也不会有这种复杂度的线性DP(至少这个题看上去不是这样).所以我们考虑N^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 ...
随机推荐
- Mariadb之复制过滤器
mariadb的主从复制集群,默认情况下是把主库上的所有库进行复制,只要在主库上产生写操作,从库基于主库的二进制日志做重放,从而实现把主库的上的库表复制到从库:复制过滤器指的是我们仅复制一个或几个数据 ...
- 「树形DP」洛谷P2607 [ZJOI2008]骑士
P2607 [ZJOI2008]骑士 题面: 题目描述 Z 国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的 ...
- 帝国の狂欢(种树)(可撤销DP)
题目描述 马上就要开学了!!! 为了给回家的童鞋们接风洗尘,HZOI帝国的老大决定举办一场狂欢舞会. 然而HZOI帝国头顶上的HZ大帝国十分小气,并不愿意给同学们腾出太多的地方.所以留给同学们开par ...
- Django---进阶2
目录 数据的查,改,删 django orm中如何创建表关系 django请求生命周期流程图(必会) 路由层 路由匹配 无名分组 有名分组 无名有名是否可以混合使用 反向解析 作业 数据的查,改,删 ...
- Python函数06/装饰器
Python函数06/装饰器 目录 Python函数06/装饰器 内容大纲 1.装饰器 1.1 开放封闭原则 1.2 装饰器 2.今日练习 内容大纲 1.装饰器 1.装饰器 1.1 开放封闭原则 扩展 ...
- A Mountaineer 最详细的解题报告
题目来源:A Mountaineer (不知道该链接是否可以直接访问,所以将题目复制下来了) 题目如下: D - A Mountaineer Time limit : 2sec / Stack lim ...
- 浏览器常见攻击方式(XSS和CSRF)
常见的浏览器攻击分为两种,一种为XSS(跨站脚本攻击),另一种则为CSRF(跨站请求伪造). XSS(跨站脚本攻击) 定义 XSS 全称是 Cross Site Scripting,为了与“CSS”区 ...
- Kafka Eagle V2.0.0新版预览
1.概述 Kafka Eagle是一款用于管理Kafka的监控系统,且完全开源.当前Kafka Eagle发布了2.0.0版本.今天笔者就为大家来介绍一下2.0.0更新了哪些功能. 官网地址:http ...
- 【C#】WebService接受跨域请求及返回json数据
问题概述 通过Web Service发布服务供客户端调用是一种非常简单.方便.快速的手段,并且服务发布后会有一个服务说明页面,直观明了,如图: 一般情况下,在web页面中的JavaScript中调用W ...
- React Native 适配Android物理返回键,实现连续两次点击退出
一直使用iPhone作为测试机开发,提交给测试同事Android版本后发现很多适配问题,其中一个非常明显的是,弹出一个modal后,点击Android的返回键,modal不会消失,直接navigati ...