zoukankan      html  css  js  c++  java
  • 博弈论

    巴什博奕:http://acm.hdu.edu.cn/showproblem.php?pid=1846

    一堆 n 个物品,两个人,每次最多只能拿走 m 个,先取完胜利;

    分析:

    1~m 个物品先手胜,m+1个物品后手胜利;

    推广: n = (m+1)*r + s,先手只要第一次拿走 s,后手每次也不能拿走(m+1),那么先手只要补上就可以了;也就是说如果 n % (m+1) !=0,先手必胜;

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 int main()
     6 {
     7     int c;
     8     scanf("%d",&c);
     9     while(c--) {
    10         int n,m;
    11         scanf("%d%d",&n,&m);
    12         if(n%(m+1))
    13             puts("first");
    14         else puts("second");
    15     }
    16     return 0;
    17 }
    View Code

    威佐夫博弈:http://acm.hdu.edu.cn/showproblem.php?pid=1527

    两堆物品,每次从一堆中取,或者从两堆中取相同多的物品,谁先取完谁胜利;

    分析:

    面对(0,0)状态先手输了(专业名词是:奇异状态);(1,2),(3,5);

    现在给你一个状态,看是否是先手必输状态(奇异状态);

    可以发现,两者的差值 x * 1.618 ((1+sqrt(5))/2) 黄金分割 == 较小者;

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 int main()
     6 {
     7     int a,b;
     8     while(~scanf("%d%d",&a,&b)) {
     9 
    10         int aa = min(a,b);
    11         int bb = max(a,b);
    12 
    13         int tmp = (bb - aa)*((1+sqrt(5))/2);
    14         if(tmp==aa)
    15             puts("0");
    16         else puts("1");
    17     }
    18 
    19     return 0;
    20 }
    View Code

    Nim博弈:http://acm.hdu.edu.cn/showproblem.php?pid=1849

    n 堆物品,每次从一堆物品中拿走若干个,谁先取完谁胜利;

    分析:

    可以通过由必输状态推其父亲结点为必胜状态得到;当然如果 n 较多,每堆物品数量很多,状态数目太多了,就不适合了;将每一堆物品异或,sum 等于  1,先手必胜;

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 int main()
     6 {
     7     int m;
     8     while(scanf("%d",&m),m) {
     9         int k;
    10         int sum = 0;
    11         for(int i=0;i<m;i++)
    12         {
    13             scanf("%d",&k);
    14             sum^=k;
    15         }
    16 
    17         if(sum)
    18             puts("Rabbit Win!");
    19         else puts("Grass Win!");
    20 
    21     }
    22 
    23     return 0;
    24 }
    View Code

    SG函数:http://acm.hdu.edu.cn/showproblem.php?pid=1848

    游戏和的SG函数等于各个子游戏SG函数的Nim和;

    SG(x) = mex(S)

    S:是 x 的后继状态的集合SG函数值;

    mex(S) : 是不在 S 集合中的最小非负整数;

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const int maxn = 1010;
     6 
     7 int f[maxn];
     8 int sg[maxn];
     9 bool vis[maxn];
    10 
    11 int main()
    12 {
    13     int m,n,p;
    14 
    15     f[1] = 1;
    16     f[2] = 2;
    17     for(int i=3;i<maxn;i++)
    18         f[i] = f[i-1] + f[i-2];
    19 
    20     sg[0] = 0;
    21     for(int i=1;i<maxn;i++) {
    22         memset(vis,0,sizeof(vis));
    23 
    24         for(int j=1;f[j]<=i;j++)
    25             vis[sg[i-f[j]]] = 1;
    26 
    27         for(int j=0;;j++)
    28         {
    29             if(!vis[j])
    30             {
    31                 sg[i] = j;
    32                 break;
    33             }
    34         }
    35 
    36     }
    37 
    38 
    39     while(scanf("%d%d%d",&m,&n,&p)) {
    40         if(m==0&&n==0&&p==0)
    41             break;
    42         int sum = 0;
    43         sum ^=sg[m];
    44         sum ^=sg[n];
    45         sum ^=sg[p];
    46         if(sum)
    47             puts("Fibo");
    48         else puts("Nacci");
    49     }
    50     return 0;
    51 }
    View Code
  • 相关阅读:
    45到数据库查询题
    Error: Could not link: /usr/local/share/doc/homebrew
    根据两点坐标,计算连线与坐标轴间的夹角(弧度、角度)
    excel2json
    Mac下的unity兼容问题,打开项目提示错误:!GetPersistentManager().IsStreamLoaded(assetPath)
    Linker Command failed with exit code 1
    module.exports与exports区别
    Nginx配置SSL证书部署HTTPS方法
    Option path is not valid. Please refer to the README.
    javascript中call()、apply()、bind()的用法终于理解
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6753517.html
Copyright © 2011-2022 走看看