博弈论(巴什博弈、 威佐夫博弈、尼姆博弈,斐波那契博弈)

巴什博弈:只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个。最后取光者得胜。
必败态:n%(m+1)==0
由题可知当你始终将所生物品数目保持在所取得数值得最大数值多一得倍数时,可以使物品数目始终保持在该情况,最终取到最后一次

Scanner sc=new Scanner(System.in);
  int n=sc.nextInt();
  int m=sc.nextInt();
  if(n%(m+1)==0) {
     
   System.out.println("NO");
  }else System.out.println("YES");

威佐夫博弈:有两堆各若干个物品,两个人轮流从任一堆取至少一个或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜。
b[k]= a[k] + k
a[k]=[k(1+√5)/2] k=1.618
必败态:(0,0)、(1,2)、(3,5)、(4,7)、(6,10)、(8,13)、(9,15)、(11,18)、(12,20)
性质一:任何自然数都包含在一个且仅有一个必败态中。
性质二:任意操作都可将奇异局势变为必胜态。
性质三:采用适当的方法,可以将必胜态变为必败态。


  Scanner sc=new Scanner(System.in);
  int n=sc.nextInt();
  int m=sc.nextInt();
  int []arr=new int [1000];
  for(int i=0;i<1000;i++) {
     
   arr[i]=(int) (i*(1+Math.sqrt(5))/2);
  }
  if(m>n) {
     
   int x=m;
   m=n;
   n=x;
  }
  for(int i=0;i<1000;i++) {
     
   if(arr[i]==n) {
     
    if(arr[i]+i==m) {
     
     System.out.println("NO");
     break;
    }else {
     
     System.out.println("YES");
     break;
    }
   }
  }
 

尼姆博弈:有三堆各若干个物品,两个人轮流从某一堆取任意多的物品,规定每次至少取一个,多者不限,最后取光者得胜。
必胜态:(0,k,k+m)(0,0,k)(m,k,k)
必败态:(0,0,0)(0,k,k)
将其和二进制联系在一起可知
必败态:abc=0
必胜态:abc!=0

Scanner sc=new Scanner(System.in);
  int a=sc.nextInt();
  int b=sc.nextInt();
  int c=sc.nextInt();
  if((a^b^c)==0) {
     
   System.out.println("NO");
  }else {
     
   System.out.println("YES");
  }

斐波那契博弈:有一堆个数为n的石子,游戏双方轮流取石子,满足:1)先手不能在第一次把所有的石子取完;2)之后每次可以取的石子数介于1到对手刚取的石子数的2倍之间(包含1和对手刚取的石子数的2倍)。约定取走最后一个石子的人为赢家,求必败态。
必败态:如果n是一个斐波那契数,那么一定是必败态(与上限无关,只要不能直接全部取完)。
Fibonacci数列:f[n]:1,2,3,5,8,13,21,34,55,89,…
当i=2时,先手只能取1颗,显然必败,结论成立。
假设当i<=k时,结论成立。
则当i=k+1时,f[i] = f[k]+f[k-1]。 则我们可以把这一堆石子看成两堆,简称k堆和k-1堆。(一定可以看成两堆,因为假如先手第一次取的石子数大于或等于f[k-1],则后手可以直接取完f[k],因为f[k] < 2*f[k-1])
可将一堆分为两堆:其中一对为数列中尽可能大的数则我们可以把n写成 n = f[a1]+f[a2]+……+f[ap]。
如果先手取任何一个数,后手可以通过操作使物品数目仍为若干个数列中的数的和

Scanner sc=new Scanner(System.in);
  int n=sc.nextInt();
  int arr[]=new int [100];
  arr[0]=1;
  arr[1]=1;
  for(int i=2;i<100;i++) {
     
   arr[i]=arr[i-1]+arr[i-2];
   if(n==arr[i]) {
     
    System.out.println("NO");
    return;
   }
  }
  System.out.println("YES");

对最后一中博弈的理解有点差,有待改进

你可能感兴趣的:(算法题目)