• 1.巴什博弈


    所谓博弈,就是两人轮流进行决策,并且两人都使用最优策略来获取胜利。通俗的说就是两个人都想获得胜利,两个人都有头脑,并且不会失误。博弈的次数是有限的,两人遵循的规则是相同的。

      有一堆石子,共有n块,两个人轮流取石子,每次至少取1块,最多取m个,最后取光者获胜(假设A,B两个人,规定A先操作)。

    (1)当n=(m+1)*k时,(k为任意正整数),当A先取石子时,A取X块石子,无论X为多少,B只要取(m+1-x),则B必胜,此时为A的必败态。

    (2)当n=(m+1)*k+r(k,r为任意正整数,r不大于m),此时A先取r块,那么B始终处在(m+1)*k的状态,由(1)可知,此时A一定赢,为A的必胜态。

    通过以上就可以变形从而解决很多问题。。

    例1:假设有一个箱子,可以装n个物品,每次最多可以装m个,最少可以装1个,A,B轮流操作,最后装满箱子的人获胜。

    伪代码如下:

    if(n%(m+1))

    A获胜

    else

    B获胜

    例2:

    假设一堆有n个物品,每次最多取m个,最少取1个,最后取光者输(A先进行)

    伪代码:

    if((n-1)%(m+1)==0)

    B 获胜

    else

    A获胜

    看完基本原理刷几道水题吧,啊哈哈。。。

    HDU1846   http://acm.hdu.edu.cn/showproblem.php?pid=1846

    代码如下:

     1 #include<stdio.h>
     2 #include<algorithm>
     3 #include<iostream>
     4 using namespace std;
     5 int main()
     6 {
     7 int t,m,n;
     8 cin>>t;
     9 while(t--){
    10 cin>>n>>m;
    11 if(n%(m+1))
    12 cout<<"first"<<endl;
    13 else cout<<"second"<<endl;
    14 }
    15 }
    View Code

    这个是最基本的啦,直接套模板。

    再看一个题吧

    HDU1847  http://acm.hdu.edu.cn/showproblem.php?pid=1847

    这个题就是在巴什博弈的模板的基础上小小的改动啦一下,思考一下就好啦。。

    题目说每次取牌的数目只能是2的幂数,且每次Kiki先开始取牌,我们从特殊情况开始讨论

    1.当牌数n就是2的幂数的时候,Kiki直接拿走所有的牌,此时Kiki获胜。

    2.当牌数n不是恰好是2的幂数,这个时候如果把牌分成x个部分,每个部分都是由2的幂数组成,那么如果x为奇数,就是Kiki赢,否则就是Cici赢。

    思路理解啦,咱们来看代码吧,这个思路是从学长那里借鉴来的,哈哈!!!!!!!!!!

     1 #include<stdio.h>
     2 #include<iostream>
     3 #include<string.h>
     4 #include<algorithm>
     5 using namespace std;
     6 const int maxn=1005;
     7 bool used[maxn];
     8 void check()
     9 {
    10 int n;
    11 memset(used,false,sizeof(used));
    12 for(int i=0;i<maxn;i++){
    13 if(!used[i]){
    14 int shu=1;
    15 while(shu+i<maxn){
    16 used[shu+i]=true;
    17 shu<<=1;
    18 }
    19 }
    20 }
    21 
    22 }
    23 int main(){
    24 check();
    25 int m;
    26 while(cin>>m){
    27 if(used[m]){
    28 cout<<"Kiki"<<endl;
    29 
    30 }
    31 else
    32 
    33 cout<<"Cici"<<endl;
    34 }
    35 }
    View Code

     针对这道题,还有另外一种想法。。

    题目说的是2的幂次,那么如果每次留给对手的都是3的倍数的话,对手如果取1,你就可以再取一点点,仍然留给对手3的倍数,如果对手取2的幂次,那么你就直接取1啦嘛。。

    代码如下:

     1 #include<stdio.h>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<string.h>
     5 using namespace std;
     6 int main(){
     7 int n;
     8 while(cin>>n){
     9     if(n%3==0)
    10         cout<<"Cici"<<endl;
    11 
    12 
    13 else cout<<"Kiki"<<endl;
    14 }
    15 }
    View Code
    你若盛开,清风自来...
  • 相关阅读:
    [CTF]跳舞的小人
    [CTF]Rabbit加密
    [CTF]ROT5/13/18/47编码
    [CTF]URL编码
    [CTF]unicode编码
    [CTF]培根密码
    电机控制总结
    stm32f4定时器配置
    MOS管测量好坏测量方法
    四元数
  • 原文地址:https://www.cnblogs.com/shangjindexiaoqingnian/p/5700431.html
Copyright © 2020-2023  润新知