博弈问题

来源:互联网 发布:域名被攻击解决办法 编辑:程序博客网 时间:2024/04/29 20:38

博弈问题概述    

        常见的博弈类问题有三种:巴什博弈、威佐夫博弈和尼姆博弈。

        一般的思路都是寻找奇异局势(必败态)。

        必败态:下一步无论如何处理都会达到必胜态;

        必胜态:下一步至少存在一种处理可以达到必败态。

        如果一开始是一个奇异局势,则先手必败;否则,先手必赢(如果双方都懂得游戏规则)。

巴什博弈

问题描述

        最简单的一类博弈问题。只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个。最后取光者得胜。

解决思路

        显然,如果n=m+1,那么由于一次最多只能取m个,所以,无论先取者拿走多少个,后取者都能够一次拿走剩余的物品,后者取胜。

        因此我们发现了如何取胜的法则:

        如果n=(m+1)r+s,(r为任意自然数,s≤m),那么先取者要拿走s个物品,如果后取者拿走k(≤m)个,那么先取者再拿走m+1-k个,结果剩下(m+1)(r-1)个,以后保持这样的取法,那么先取者肯定获胜。总之,要保持给对手留下(m+1)的倍数,就能最后获胜。

例子

HDU 1846

        最简单的巴什博弈。
#include <stdio.h>int main(){    int C;    int n, m;    scanf("%d", &C);    while (C --)    {        scanf("%d%d", &n, &m);        if (n%(m+1) == 0)            printf("second\n");        else            printf("first\n");    }    return 0;}

HDU 1847

        巴什博弈的变形。
        只要保证剩下的数量为3的倍数,即可确保胜利。因为留下3的倍数时,对手有两种情况:
        1):如果轮到对方抓牌时只剩3张牌,对方要么取1张,要么取2张,剩下的你全取走,win! 
        2):如果轮到对方抓牌时还剩3*k张牌,对手不管取多少,剩下的牌数是3*x+1或者3*x+2。轮到你时,你又可以构造一个3的倍数。 所以无论哪种情况,当你留给对手为3*k的时候,你是必胜的。
#include <stdio.h>int main(){    int n;    while (scanf("%d", &n) != EOF)    {        if (n%3 == 0)            printf("Cici\n");        else            printf("Kiki\n");    }    return 0;}

威佐夫博弈

问题描述

        威佐夫博奕(Wythoff Game):有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜。

解决思路

        解决思路同样是寻找奇异局势。
        

        用(ak, bk)(ak ≤ bk ,k=0, 1, 2, ... , n)表示两堆物品的数量并称其为局势。很显然,(0, 0)是一个奇异局势。前几个奇异局势是:(0, 0)、(1, 2)、(3, 5)、(4, 7)、(6, 10)、(8, 13)、(9, 15)、(11, 18)、(12, 20)。

        可以看出,a0=b0=0,ak是未在前面出现过的最小自然数,而 bk= ak + k。

        关于奇异局势的几个性质:

        (1):任何自然数都包含在一个且仅有一个奇异局势中;

        (2):任意操作都可将奇异局势变为非奇异局势;

        (3):采用适当的方法,可以将非奇异局势变为奇异局势。

例子

尼姆博弈

问题描述

        有三堆各若干个物品,两个人轮流从某一堆取任意多的物品,规定每次至少取一个,多者不限,最后取光者得胜。

解决思路

        用一个三元组(a, b, c)表示局势。任何奇异局势 (a, b, c)都有a ^ b ^ c = 0。
        如果我们面对的是一个非奇异局势(a,b,c),要如何变为奇异局势呢?
        假设 a < b < c,我们只要将 c 变为 a ^ b,即可,因为有如下的运算结果:a ^ b ^ (a ^ b)=(a ^ a) ^ (b ^ b)=0 ^ 0=0。要将c 变为a ^ b,只要从 c中减去 c - (a ^ b)即可。

例子

原创粉丝点击