博弈论(1): 巴什博奕

(一)巴什博奕(Bash Game):只有一堆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)的倍数,就能最后获胜。
    这个游戏还可以有一种变相的玩法:两个人轮流报数,每次至少报一个,最多报十
个,谁能报到100者胜。
巴什博弈博弈论里面最简单的一种形式。以下题目利用巴什博弈可以轻松解决:

1. http://acm.hdu.edu.cn/showproblem.php?pid=1846 (brave game)

2. http://acm.hdu.edu.cn/showproblem.php?pid=2147 (kiki's game)

3. http://acm.hdu.edu.cn/showproblem.php?pid=2149 (public sale)

4. http://acm.hdu.edu.cn/showproblem.php?pid=2188 (选拔志愿者)

下面介绍分析此类题目的通用方法:P/N分析:

P点: 即必败点,某玩家位于此点,只要对方无失误,则必败;

N点: 即必胜点,某玩家位于此点,只要自己无失误,则必胜。

三个定理:

定理:

     一、 所有终结点都是必败点P(上游戏中,轮到谁拿牌,还剩0张牌的时候,此人就输了,因为无牌可取);

    二、所有一步能走到必败点P的就是N点;

    三、通过一步操作只能到N点的就是P点;

以上题目均可以通过P/N分析法来解决。

 

View Code
 1 /*
 2 problem : 2188
 3 */
 4 #include<stdio.h>
 5 int main(){
 6     int T;
 7     scanf("%d",&T);
 8     while(T--){
 9         int n,m;
10         scanf("%d%d",&n,&m) ;
11         if( n % (m+1)  )
12             printf("Grass\n") ;
13         else
14             printf("Rabbit\n");
15     }
16     return 0;
17 }
18 
19 /*
20 problem : 2149
21 */
22 #include<stdio.h>
23 int main(){
24     int n,m;
25     while(scanf("%d%d",&n,&m)!=EOF){
26         if(n%(m+1)){
27             while(n < m)
28                 printf("%d ",n++) ;
29             printf("%d\n",n%(m+1)) ;
30         }
31         else
32             printf("none\n") ;
33     }
34     return 0;
35 }
36 
37 /*
38 problem : 2147
39 */
40 #include<stdio.h>
41 int main(){
42     int n,m;
43     while(scanf("%d%d",&n,&m) && n){
44         if(n%2 && m%2)
45             printf("What a pity!\n");    
46         else
47             printf("Wonderful!\n");
48     }
49     return 0;
50 }
51 
52 /*
53 problem : 2188
54 */
55 #include<stdio.h>
56 int main(){
57     int T;
58     scanf("%d",&T);
59     while(T--){
60         int n,m;
61         scanf("%d%d",&n,&m) ;
62         if( n % (m+1)  )
63             printf("Grass\n") ;
64         else
65             printf("Rabbit\n");
66     }
67     return 0;
68 }

 

 

posted @ 2012-08-17 01:49  3111006139  阅读(306)  评论(0编辑  收藏  举报