博弈论小结

转载出处:http://blog.csdn.net/ac_gibson/article/details/41624623


【巴什博奕】:
    只有一堆n个物品,两个人轮流从中取物
    规定每次最少取一个,最多取m个,最后取光者为胜。
例题:
    HDU4764  Stone:
    题目大意:
        Tang和Jiang轮流写数字
        Tang先写每次写的数x满足1<=x<=k
        Jiang每次写的数y满足1<=y-x<=k
        谁先写到不小于n的数算输。
    结论:
        r=(n-1)%(k+1),r=0时Jiang胜,否则Tang胜。

    
   

#include <iostream>  
    using namespace std;  
    int main()  
    {  
        int n,m;  
        while(cin>>n>>m)  
          if(n%(m+1)==0)  cout<<"后手必胜"<<endl;  
          else cout<<"先手必胜"<<endl;  
        return 0;  
    }  


    
    
【威佐夫博弈】
    有两堆各若干的物品,两人轮流从其中一堆取至少一件物品,至多不限
    或从两堆中同时取相同件物品
    规定最后取完者胜利。

    
    #include <cstdio>  
    #include <cmath>  
    #include <iostream>  
    using namespace std;  
    int main()  
    {  
        int n1,n2,temp;  
        while(cin>>n1>>n2)  
        {  
            if(n1>n2)  swap(n1,n2);  
            temp=floor((n2-n1)*(1+sqrt(5.0))/2.0);  
            if(temp==n1) cout<<"后手必胜"<<endl;  
            else cout<<"先手必胜"<<endl;  
        }  
        return 0;  
    }  


    
【尼姆博弈】
    有任意堆物品,每堆物品的个数是任意的
    双方轮流从中取物品,每一次只能从一堆物品中取部分或全部物品
    最少取一件,取到最后一件物品的人获胜。

  
 
    #include <cstdio>  
    #include <cmath>  
    #include <iostream>  
    using namespace std;  
    int main()  
    {  
        int n,ans,temp;  
        while(cin>>n)  
        {  
            temp=0;  
            for(int i=0;i<n;i++)  
            {  
                cin>>ans;  
                temp^=ans;  
            }  
            if(temp==0)  cout<<"后手必胜"<<endl;  
            else cout<<"先手必胜"<<endl;  
        }  
        return 0;  
    } 


    
【斐波那契博弈】
     有一堆物品,两人轮流取物品
     先手最少取一个,至多无上限,但不能把物品取完
     之后每次取的物品数不能超过上一次取的物品数的二倍且至少为一件
     取走最后一件物品的人获胜。
例题
    HDU2516(代码如下)

    
 
  #include <iostream>    
    #include <string.h>    
    #include <stdio.h>    
    using namespace std;    
    const int N = 55;      
    int f[N];     
    void Init()    
    {    
        f[0] = f[1] = 1;    
        for(int i=2;i<N;i++)    
            f[i] = f[i-1] + f[i-2];    
    }      
    int main()    
    {    
        Init();    
        int n;    
        while(cin>>n)    
        {    
            if(n == 0) break;    
            bool flag = 0;    
            for(int i=0;i<N;i++)    
            {    
                if(f[i] == n)    
                {    
                    flag = 1;    
                    break;    
                }    
            }    
            if(flag) puts("Second win");    
            else     puts("First win");    
        }    
        return 0;    
    }   


   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值