三种博弈

以下是大神对博弈问题的总结, 让我受益匪浅:

博弈最重要的三点:(以后做题经常利用这三点性质):

注意:P点是必败局势,就是说无论是谁面对P点都必败

N点是必胜局势,也就是说面对此局势的人有必胜策略

终结点,是结局,无法再继续博弈

(1)所有终结点是必败点(P点); //容易理解

(2)从任何必胜点(N点)操作,至少有一种方法可以进入必败点(P点); //就是那种我们要走的方法

(3)无论如何操作,从必败点(P点)都只能进入必胜点(N点)//仔细思考,发现确实是这样

综上博弈中,一个状态不是必胜,就是必败

很多时候,找不到规律时,可以利用以上的性质搜索解决问题。

 

巴什博弈(容易理解,没什么好说的)

只有一堆n个物品,两人轮流从这堆物品中取物,规定每次至少取一个,最多取m个。最后取光者获胜。

先手胜利的条件: n = (m+1)c+s时;取走s个;

也就是说:一个人面对当前石子个数是m+1的倍数时,这个人就输了;

 

典型例题:http://acm.hdu.edu.cn/showproblem.php?pid=1846

代码:

#include<stdio.h>

int main(){
    int T, n, m;
    
    scanf("%d", &T);
    while(T--){
        scanf("%d %d", &n, &m);
        
        if(n % (m + 1) == 0)
            printf("second\n");
        else
            printf("first\n");
    }
    return 0;
}


类似的题目还有两个人轮流报数,谁先报到100,谁就赢了。。。


威佐夫博弈(结论好理解,证明太难了我不会):

有两堆石子,数量任意,可以不同。

游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,

一是可以在任意的一堆中取走任意多的石子;

二是可以在两堆中同时取走相同数量的石子。

最后把石子全部取完者为胜者。

(0,0)是终结点

(1,2)是之前一个必败点

 (3,5),(4,7),(6,10),(8,13)...都是必败点

找规律发现每个自然数都只出现一次,并且是前面没有出现过的最小自然数。

这里有一个结论:跟黄金分割有关

我们把第k个必败点的两个数表示成(ak,bk);

那么

         b(k) = a(k) + k;  //看规律得出的

         a(k) = k * (1 + sqrt(5))/2   //关于这个公式的出处http://scimath.unl.edu/MIM/files/MATExamFiles/Cotton_MATpaper_Final_EDITED.pd或者在http://yjq24.blogbus.com/logs/42826226.html

 

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1527

 

代码:

#include<stdio.h>
#include<math.h>

int main(){
    int a, b, k, temp;
    int max, min;
    
    while(scanf("%d %d", &a, &b) != EOF){
        if(a == b && a != 0){
            printf("1\n");
            continue;
        }
    //    if(a == b && a == 0){
    //        printf("0\n");
    //        continue;
    //    }
        max = a > b ? a : b;
        min = a < b ? a : b;
        k = max - min;
        
        temp = (k * (sqrt(5.0) + 1)) / 2;
        if(temp == min && temp + k == max){
            printf("0\n");
        }    
        else
            printf("1\n");
    }
    return 0;
}

斐波那契博弈:

有一堆石子,两个人轮流从其中取走一定的石子,取走最后所有石子的人为赢家,不过得遵循如下规则:

 

1.第一次取不能取完,至少取1颗.

 

2.从第二次开始,每个人取的石子数至少为1,至多为对手刚取的石子数的两倍。

 

结论:如果一个人当前面对的石子数是斐波那契数,那么这个人就一定输了.(证明在这里:http://blog.csdn.net/dgq8211/article/details/7602807,证明过程很复杂,但是记住结论很轻松)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2516

代码:

#include<stdio.h>
#include<string.h>

int main(){
    int n;
    int a, b, c;
    
    while(scanf("%d", &n), n){
        a = 1, b = 1;
        c = 2;
        while(c < n){
            c = a + b;
            a = b;
            b = c;
        }
        if(c == n){
            printf("Second win\n");
        }
        else
            printf("First win\n");
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值