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

    一、巴什博弈(Bash Game)

          只有一堆n个物品,两个人从轮流中取出(1~m)个;最后取光者胜。

          考虑到 若n=m+1 那么 第一个人不论如何取都不能取胜。

          进一步我们发现 若 n=k*(m+1)+r; 先取者拿走 r 个,那么后者再拿(1~m)个

          n=(k-1)*(m+1)+s; 先取者再拿走s 个 最后总能造成 剩下n=m+1 的局面。

          因此,此时先手有必赢策略。

          相对应的,若n=k*(m+1) 那么先取者必输。

    #include<iostream>
    using namespace std;
    int main() {
        int n, m;
        while (scanf("%d%d", &n, &m) != EOF) {
            if (n%(m+1) != 0)
              printf("先取者赢
    ");
            else
              printf("先取者输
    ");
        }
    } 

    二、尼姆博弈(Nimm Game)

    所有物品数目二进制异或    为0,则先手必输
    所有物品数目二进制异或不为0,则后手必输

    1、问题模型:有三堆各若干个物品,两个人轮流从某一堆取任意多的物品,规定每次至少取一个,多者不限,最后取光者得胜。

    2、解决思路:用(a,b,c)表示某种局势,显证(0,0,0)是第一种奇异局势,无论谁面对奇异局势,都必然失败。第二种奇异局势是(0,n,n),只要与对手拿走一样多的物品,最后都将导致(0,0,0)。

      搞定这个问题需要把必败态的规律找出:(a,b,c)是必败态等价于a^b^c=0(^表示异或运算)。

      证明:(1)任何p(a,b,c)=0的局面出发的任意局面(a,b,c’);一定有p(a,b,c’)不等于0。否则可以得到c=c’。

          (2)任何p(a,b,c)不等于0的局面都可以走向 p(a,b,c)=0的局面

           (3)对于 (4,9,13) 这个容易验证是奇异局势 

                 

           其中有两个8,两个4,两个1,非零项成对出现,这就是尼姆和为  零的本质。别人要是拿掉13里的8或者1,那你就拿掉对应的9  中的那个8或者1;别人要是拿        掉13里的4,你就拿掉4里的4;  别人如果拿掉13里的3,就把10作分解,然后想办法满 足非零项成对即可。

    3、推广一:如果我们面对的是一个非奇异局势(a,b,c),要如何变为奇异局势呢?假设 a < b< c,我们只要将 c 变为 a^b,即可,因为有如下的运算结果: a^b^(a^b)=(a^a)^(b^b)=0^0=0。要将c 变为a^b,只从 c中减去 c-(a^b)

    #include<iostream>
    using namespace std;
    int main() {
        int arr[10];
        int n;
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
          scanf("%d", &arr[i]);
        int ans = arr[0];
        for (int i = 1; i < n; i++)
        ans ^= arr[i];
      if (ans)
        printf("先取者赢
    ");
      else
        printf("先取者输
    ");
    } 

    三、威佐夫博奕

    https://baike.baidu.com/item/%E5%A8%81%E4%BD%90%E5%A4%AB%E5%8D%9A%E5%BC%88/19858256?fr=aladdin

    #include<iostream>
    using namespace std;
    int main() {
      int n, m;
      while (scanf("%d%d", &n, &m) != EOF) {
          if (n < m) swap(n, m);
            int k = n-m;
            n = (int)(k*(sqrt(5)+1)/2.0) 
            if (n!=m)
          printf("先取者赢
    ");
        else
          printf("先取者输
    ");
        }
    } 
  • 相关阅读:
    POJ 3710 Christmas Game#经典图SG博弈
    POJ 2599 A funny game#树形SG(DFS实现)
    POJ 2425 A Chess Game#树形SG
    LeetCode Array Easy 122. Best Time to Buy and Sell Stock II
    LeetCode Array Easy121. Best Time to Buy and Sell Stock
    LeetCode Array Easy 119. Pascal's Triangle II
    LeetCode Array Easy 118. Pascal's Triangle
    LeetCode Array Easy 88. Merge Sorted Array
    ASP.NET MVC 学习笔记之 MVC + EF中的EO DTO ViewModel
    ASP.NET MVC 学习笔记之面向切面编程与过滤器
  • 原文地址:https://www.cnblogs.com/a863886199/p/7811216.html
Copyright © 2011-2022 走看看