您的位置:首页 > 运维架构 > Shell

HDU2188——悼念512汶川大地震遇难同胞——选拔志愿者(Bash Game巴士博弈)(我去,名字肿么这么长)

2016-03-31 11:47 573 查看
题目链接

开始研究博弈论了。。。挑了些入门题,,,就决定是它了——巴士博弈入门题,这道题题目蛮长的,但代码短的不敢信,所以姑且就此简单说一下巴士博弈——

巴士博弈:有一堆XX(XX可以为任何东西),个数为n,然后有两个很聪明的二货闲的无聊轮流从这一堆XX中取若干个XX,且每次最少取一个,最多取m个,最后能一次取完的获胜。

那么问题来了,,,谁能赢呢?是先手还是后手,这里的前提已经提过,这两人虽然是二货但属于那种比较聪明的二货(二货中的战斗货),所以他们每次的决策绝对是最优决策,也就是当前状态下能做的最好决策,这也是博弈论的关键,对此我们姑且这样想,假如n=m+1;那么作为先手,无论取多少(假设取k,1<=k<=m),那么剩余数n-k满足(1<=n-k<=m),故后者可一次取完,也就是后手胜。所以以此类推,剩余数n=m+1时是一种必败状态,所以要把这种状态留给对手。同理,当n%(m+1)==0时也是必败状态,因为无论此状态怎么取,对手总能使此状态维持为n%(m+1)==0,最后当n==m+1时,双方取各自的最后一次XX,游戏结束,后手胜。所以条件n%(m+1)是否为0是制胜关键,对于先手,当n%(m+1)!=0时他可以先取n%(m+1)的货物,这样剩下的n就满足n%(m+1)==0了,这样先手就把这种必败状态留给了后手,同理当一开始n%(m+1)==0时,也就是先手一开始就拿到必败状态时,毫无疑问,后手胜,这就是巴士博弈,博弈的关键就是n%(m+1)是否为0。

下面对此做个变形,改变一下获胜条件——假如最后取完的失败。那么获胜条件又会怎么变呢,其实大家也许都在网上看过了,条件和原来的条件只是做了细微的变化(即(n-1)%(m+1)==0为必败状态),为什么如此修改其实道理也很简单,就是假设从总物品中提出一个XX,这个XX在其他XX没被取完的情况下不能被拿走,这样n就等于n-1了,那么(n-1)%(m-1)==0就是原巴士博弈的必败状态,但变形过后我们知道此时取完最后一个物品的人是失败者,为什么会这样,那是因为事先我们就已经拿出了一个XX,所以接下来另一人就会拿走这个XX取得胜利,所以这样理解就能比较容易看懂此变形式了。

巴士博弈原理讲完,我们就回到正题,也就是杭电的这道题,选志愿者,题目说是往钱箱里塞钱,超过n获胜,并非取物品,但实际和从装满n元钱的钱箱里取m元是一个道理,所以也就是个纯巴士博弈,不多说了,直接看代码吧~~~

#include<stdio.h>

int main()
{
int temp;
scanf("%d",&temp);
while(temp--)
{
int n, m;
scanf("%d%d",&n,&m);
int s=n%(m+1);
if(s)printf("Grass\n");
else printf("Rabbit\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: