记得大二的时候还研究过,后来一直放着也没弄过。 不过今天做TC的时候自己分析到了博弈,发现怎么都不记得了。复习一下.......... 以后工作可能要与Java 打交道了,所以 ......还是练练Java实现吧....


寻找平衡状态(也称必败态, 奇异局势),(满足:任意非平衡态经过一次操作可以变为平衡态)
(一)巴什博奕(Bash Game):
只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个.最后取光者得胜.
n = (m+1)r+s , (r为任意自然数,s≤m), 即n%(m+1) != 0, 则先取者肯定获胜

hdu 4674

 

import java.util.Scanner;

public class Main {
	/*
	 * 谁先取到n-1谁就赢了
	 */
	public static final double Gold = ((1+ Math.sqrt(5.0))/2.0);
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n, k;
		while (in.hasNext()) {
			n = in.nextInt();
			k = in.nextInt();
			
			if (n == 0 && k == 0) break;
			if ((n - 1) % (k + 1) != 0) System.out.println("Tang");
			else System.out.println("Jiang");
			
		}
	}
}

 

  


(二)威佐夫博奕(Wythoff Game):
有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜.
(ak,bk)(ak ≤ bk ,k=0,1,2,...,n)表示奇异局势
求法:
ak =[k(1+√5)/2], bk= ak + k (k=0,1,2,...,n 方括号表示取整函数)
判断:
Gold=(1+sqrt(5.0))/2.0;
1)假设(a,b)为第k种奇异局势(k=0,1,2...) 那么k=b-a;
2)判断其a==(int)(k*Gold),相等则为奇异局势
(注:采用适当的方法,可以将非奇异局势变为奇异局势.
假设面对的局势是(a,b)
若 b = a,则同时从两堆中取走 a 个物体,就变为了奇异局势(0,0);
1. 如果a = ak,
1.1 b > bk, 那么,取走b - bk个物体,即变为奇异局势(ak, bk);
1.2 b < bk 则同时从两堆中拿走 ak – a[b – ak]个物体,变为奇异局势( a[b – ak] , a[b – ak]+ b - ak);
2 如果a = bk ,
2.1 b > ak ,则从第二堆中拿走多余的数量b – ak
2.2 b < ak ,则 若b = aj (j < k) 从第一堆中拿走多余的数量a– bj; (a > bj)
若b = bj (j < k) 从第一堆中拿走多余的数量a– aj; ( a > aj)

pku 1067

import java.util.Scanner;

public class Main {
	public static final double Gold = ((1+ Math.sqrt(5.0))/2.0);
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		Integer a = 0,b = 0;
		while (in.hasNext()) {
			a = in.nextInt();
			b = in.nextInt();
			if (a > b) {
				int t;
				t = a; a = b; b = t;
			}
			int k = b - a;
			if ((int)(k*Gold) == a) System.out.println(0);
			else System.out.println(1);
			
		}
	}
}

  

(三)尼姆博奕(Nimm Game):
有n堆各若干个物品,两个人轮流从某一堆取任意多的物品,规定每次至少取一个,多者不限,最后取光者得胜.
任何奇异局势(a1, a2, … , an)都有a1(+)a2(+)…(+)an =0. ( (+)为 按位与)
例题:pku 2234

import java.util.Scanner;

public class Main {
    public static final double Gold = ((1+ Math.sqrt(5.0))/2.0);
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n, k;
        while (in.hasNext()) {
            n = in.nextInt();
            int ans = 0;
            for (int i = 0; i < n; ++i) {
                k = in.nextInt();
                ans ^= k;
            }
            if (ans == 0) System.out.println("No");
            else System.out.println("Yes");
            
        }
    }
}
View Code

相关文章: