博弈dp 以I Love this Game! POJ - 1678 为例
写在前面的话
知识基础:一些基础的博弈论的方法,动态规划的一些知识
前言:博弈论就是一些关于策略或者游戏之间的最优解,动态规划就是对于一些状态之间转移的一些递推式(or 递归),dp分为很多很多种,比如状压dp我感觉其实就是一种暴力,数位dp也可以用记忆化搜索的形式解决。可见动态规划其实是解决一些不能快速解决,不能以O(1)方法解决的问题,而博弈之中,经常会出现一些O(1)方法解决的策略,或者O(n),可见博弈dp它有其不确定性(或者说有不能直接解决的方案)所以需要在博弈的基础上加上dp。举一个很简单的例子,但这个例子没有什么实质性的意义,知识为了帮助理解博弈dp,比如有一个01串,两个人轮流取其中的数字,要求下一次取的那个的下标必须比前一个取的下标要大,比如第一个人取第一个,第二个人只能取(2-n)个。很简单吧,然后问你两个人最多可以加起来取多少个1。你肯定会说这要dp啥,这要博弈啥,我就举个例子嘛。博弈在这里面就是每个人都取前一次取的那个的后面的那个是不是就是最优的啦,dp就当作枚举第一个人拿去的第一个数的下标是几,然后可以拿到多少个1,比如dp[m]就是第一个人取第m个可以拿到的最多的1的个数。
现在就来看poj-1678这道题
题意:2个人轮流拿数组里面的一个数,且要比另外一个人上一次拿的数大[a,b],第一次拿要拿[a,b]范围的数,求第一个人拿的总和比第二个人的总和最多大多少
思考:很明显,他们拿的肯定是一个比一个大(题目里说了0<a<b),所以先排个序那就是肯定是按照从左往右取的对吧。
看个样例:
6 1 2
1 3 -2 5 -3 6
把它排序之后就是:
6 1 2
-3 -2 1 3 5 6
很明显第一个人只能取1,然后第二个人取3,第一个人再取5,第二个人再取6,那么差值就是1+5-3-6 = -3
看了这个样例你肯定会感觉看了和没看一样,因为这里取的情况被锁死了,那我们来看看下一个我瞎造的样例
8 1 10
1 2 3 4 5 6 7 8
假设第一个人先后取1 3 5 7,第二个人先后取2 4 6 8,这个是符合题意的,然而差值是-4,甚至是player2赢了
假设第一个人先后取3 5 7,第二个人先后取4 6 8,这个也是符合题意的,然而差值是-3,还是player2赢了
假设第一个人先后取4 6 8,第二个人先后取5 7,这个也是符合题意的,差值为6,player1赢了
最优解就是第一个人直接就是取8,那么第二个人取不了了,差值为8,player1赢了,甚至没有给player2一个后手,太狠了
所以发现问题了吗,player1第一次取的那个数字是什么是影响结果的,同时,假如第一个人选1,第二个人直接选8也是可行,可见第二个人的选法也是影响结果的,所以这就是一个dp,或者可以说是一个记忆化的搜索。
看看代码就会知道,soga
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<cmath>
#include<stack>
#include<cstdlib>
#include <vector>
#include <set>
#include<queue> using namespace std; #define ll long long
#define llu unsigned long long
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
const int maxn = 1e4+;
int num[maxn];
int n,a,b;
int dp[maxn]; void init()
{
for(int i=;i<n;i++)
dp[i] = -INF;
}
int DP(int m)
{
if(dp[m] != -INF) //dp[m]表示如果先手取了第m个数,可以达到的最大的分差
return dp[m]; //如果第m个数已经取了,直接就return,这个不加可能会t
int ans = INF;
for(int i=m+;i<n;i++)
if(num[i]-num[m] >= a && num[i]-num[m] <= b)
ans = min(ans,num[m] - DP(i)); //dp就是枚举最后一个状态,如果最后一个状态已经涵盖了,那么之前的所有状态都涵盖了
if(ans == INF)//取不了了
return dp[m] = num[m];
return dp[m] = ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&a,&b);
init();
for(int i=;i<n;i++)
scanf("%d",&num[i]);
sort(num,num+n);
int ans = -INF;
for(int i=;i<n;i++) //枚举第一个人拿的每一个数
if(num[i] >= a && num[i] <= b)
ans = max(ans,DP(i));
printf("%d\n",ans == -INF ? : ans);
}
}
博弈dp 以I Love this Game! POJ - 1678 为例的更多相关文章
- 博弈dp入门 POJ - 1678 HDU - 4597
本来博弈还没怎么搞懂,又和dp搞上了,哇,这真是冰火两重天,爽哉妙哉. 我自己的理解就是,博弈dp有点像对抗搜索的意思,但并不是对抗搜索,因为它是像博弈一样,大多数以当前的操作者来dp,光想是想不通的 ...
- HDU 5623 KK's Number (博弈DP)
KK's Number 题目链接: http://acm.hust.edu.cn/vjudge/contest/121332#problem/K Description Our lovely KK h ...
- POJ 1678 I Love this Game!#dp博弈
http://poj.org/problem?id=1678 #include<iostream> #include<cstdio> #include<cstring&g ...
- poj 2068 Nim(博弈dp)
Nim Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 1403 Accepted: 791 Description Le ...
- tyvj P1075 - 硬币游戏 博弈DP
P1075 - 硬币游戏 From price Normal (OI)总时限:10s 内存限制:128MB 代码长度限制:64KB 背景 Background 农民John的牛喜欢玩 ...
- UVA 1558 - Number Game(博弈dp)
UVA 1558 - Number Game 题目链接 题意:20之内的数字,每次能够选一个数字,然后它的倍数,还有其它已选数的倍数组合的数都不能再选,谁先不能选数谁就输了,问赢的方法 思路:利用dp ...
- 计蒜客 取数游戏 博弈+dp
题目链接 取数游戏 思路:dp(x, y)表示先手在区间[x, y]能取得的最大分数.当先手取完,就轮到后手去,后手一定会选择当前能令他得到最大分数的策略,其实当先手在[x, y]区间两端取走一个数, ...
- Beans Game(博弈 | | DP)zoj 3057
Beans Game Time Limit: 5 Seconds Memory Limit: 32768 KB There are three piles of beans. TT and DD pi ...
- 【HDOJ5951】Winning an Auction(博弈DP)
题意:A和B两个人做一个拍卖游戏.每一轮两人分别给出一个价格,出价高者获得该轮的物品,出价相同则奇数轮A优先,偶数轮B优先. 两个人的目标都是最大化自己的商品数量,给定轮数n与两人分别的总资金a,b, ...
随机推荐
- css Media Query详解
Media Queries详解 Media Queries直译过来就是“媒体查询”,在我们平时的Web页面中head部分常看到这样的一段代码: 1 <link href="css/re ...
- visual studio 调试 不进断点 断点失效 提示当前不会命中该断点等问题解决
1.首先看一下 当前调试模式是否为debug 2. 点击[调试]>[选项和设置] 将[要求源文件与原始文件完全匹配]勾选掉 3.点击调试的最后一个选项 点击[web] 将调试器内部勾选上需要测 ...
- c#利用三层架构做一个简单的登录窗体
就个人而言,三层架构有点难理解,不知道该如何下手,各层与各层之间怎么调用 最近一直在研究三层架构,经过网上学习与多方打听写一下自己的心得.有不足之处,可以评论和私聊探讨 言归正传: 三层架构(3-ti ...
- url规范化:解决从baidu.com到www.baidu.com的
通过 301重定向可以实现 把www.baidu.com和baidu.com合并,并把之前的域名也一并合并. 有两种实现方法: 第一种方法是判断nginx核心变量host(别名功能): server ...
- 推荐一个很好用的脚本session snapper
源网址http://tech.e2sn.com/oracle-scripts-and-tools/session-snapper 内容: If you want to just download Sn ...
- MATLAB安装与注册(血泪总结)
工具/原料 R2016a_win64.iso(安装文件) Matlab 2016a Win64 Crack.rar(破解文件) 方法/步骤 1 下载R2016a_win64.iso(安装文件) ...
- Scrum第三次冲刺
1.第三次冲刺任务概述 我们设计的长大万能通系统主要实现以下几个功能: a.周边查询 b.快递代取 c.查看校内新闻动态 d.二手物品交易 第三次冲刺我们计划实现周边查询功能.可以根据评分.距离最近. ...
- github desktop项目版本控制
[git版本控制-笔记]by lijun 0.推荐学习网址:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b ...
- POJ-3267 The Cow Lexicon---删除字符匹配单词
题目链接: https://cn.vjudge.net/problem/POJ-3267 题目大意: 题意就是给出一个主串,和一本字典,问最少在主串删除多少字母,可以使其匹配到字典的单词序列. PS: ...
- POJ 1191 棋盘分割 【DFS记忆化搜索经典】
题目传送门:http://poj.org/problem?id=1191 棋盘分割 Time Limit: 1000MS Memory Limit: 10000K Total Submission ...