写在前面的话

知识基础:一些基础的博弈论的方法,动态规划的一些知识

前言:博弈论就是一些关于策略或者游戏之间的最优解,动态规划就是对于一些状态之间转移的一些递推式(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 为例的更多相关文章

  1. 博弈dp入门 POJ - 1678 HDU - 4597

    本来博弈还没怎么搞懂,又和dp搞上了,哇,这真是冰火两重天,爽哉妙哉. 我自己的理解就是,博弈dp有点像对抗搜索的意思,但并不是对抗搜索,因为它是像博弈一样,大多数以当前的操作者来dp,光想是想不通的 ...

  2. HDU 5623 KK's Number (博弈DP)

    KK's Number 题目链接: http://acm.hust.edu.cn/vjudge/contest/121332#problem/K Description Our lovely KK h ...

  3. POJ 1678 I Love this Game!#dp博弈

    http://poj.org/problem?id=1678 #include<iostream> #include<cstdio> #include<cstring&g ...

  4. poj 2068 Nim(博弈dp)

    Nim Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 1403   Accepted: 791 Description Le ...

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

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

  6. UVA 1558 - Number Game(博弈dp)

    UVA 1558 - Number Game 题目链接 题意:20之内的数字,每次能够选一个数字,然后它的倍数,还有其它已选数的倍数组合的数都不能再选,谁先不能选数谁就输了,问赢的方法 思路:利用dp ...

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

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

  8. 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 ...

  9. 【HDOJ5951】Winning an Auction(博弈DP)

    题意:A和B两个人做一个拍卖游戏.每一轮两人分别给出一个价格,出价高者获得该轮的物品,出价相同则奇数轮A优先,偶数轮B优先. 两个人的目标都是最大化自己的商品数量,给定轮数n与两人分别的总资金a,b, ...

随机推荐

  1. Python类三种方法,函数传参,类与实例变量(一)

    1 Python的函数传递: 首先所有的变量都可以理解为内存中一个对象的'引用' a = 1 def func(a): a = 2 func(a) print(a) # 1 a = 1 def fun ...

  2. Codeforces 385C 线性筛素数

    题意:给定一个数组,求[l,r] 区间,区间里的素数,数组中,能被这个素数整除的个数,再求和. 分析:区间很大,10^9了,找去区间内的素数是不可能的,但是,数组的数很小,而且要能整除区间内的素数,所 ...

  3. LG3690 【【模板】Link Cut Tree (动态树)】

    题目 终于去写\(LCT\)了 这个大爷讲的挺好的 板子 #include<algorithm> #include<iostream> #include<cstring& ...

  4. ASP.NET SignalR 与LayIM配合,轻松实现网站客服聊天室(五) 补充:历史记录 和 消息提醒

    有开发者提问怎么做历史记录功能和即使不打开聊天窗口有消息提醒功能.简单抽时间写了点代码.不过只是基本思路,具体细节没有实现. 正如前几篇博客中提到的,读取历史记录什么时候读取呢?按照常理,应该是打开聊 ...

  5. mui(手机)

    官网:http://dev.dcloud.net.cn/mui/

  6. Python—面向对象06 内置方法

    一 .isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo(object ...

  7. Dubbo源码分析之ExtensionLoader加载过程解析

    ExtensionLoader加载机制阅读: Dubbo的类加载机制是模仿jdk的spi加载机制:  Jdk的SPI扩展加载机制:约定是当服务的提供者每增加一个接口的实现类时,需要在jar包的META ...

  8. 微信小程序流量主如何开通

    2018年7月09日,微信小程序流量主全面开通,开通条件如下: 累计独立访客(UV)不低于1000          # 一共一千个人访问你的小程序就可以申请(不限时间) 有严重违规记录的小程序不予申 ...

  9. SQL3120W 不能将xx的字段值转换成 INTEGER值

    一次用DB2 Load/Import导入数据时,报错,提示SQL3120W 不能将xx的字段值转换成 INTEGER值,但目标列不可为空.未装入该行. 目标表: CREATE TABLE TEST( ...

  10. 解决问题的思路(如故事版里面有东西,却不见了)(swift里面开发比较多)

    解决问题的思路(如故事版里面有东西,却不见了) 正确效果图: 真机效果图: 内容:不见了 解决步骤:(重点讲解方法1) 1.把背景图隐藏了,如果能出现内容,说明背景图把内容遮住了.那怎么办呢,背景图是 ...