标签:style blog http color os 使用 ar strong 2014
巴什博奕(BashGame):一堆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)的倍数,就能最后获胜。
威佐夫博奕(WythoffGame):有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜。这也就是本书中提到的NIM问题;
结论:记两堆物品数量<a,b>;第n组不安全局面<a(n),b(n)>满足:a(n)+n=b(n) and a(n)=min(N-A(N-1)并B(n-1));其中N:所有正整数,A(n)={a1,.....a(n)},B(n)={b1.....b(n)};
那么可以直接根据上述结论求解,初始值:a1=1,b1=2,对给定数量的两堆物品,判断是否满足不安全局面,满足,先取者必败,否则先取者有胜利机会;算法复杂度O(N);
当然还有O(1)的公式可以解决问题:a(n) = [(1 + sqrt(5)) / 2 * n], b(n) = [(3 + sqrt(5)) / 2 * n];我们可以使用一个通项公式计算出所有不安全局面;
问题中必输态具有的性质:对于必输数对(a,b),假定a < b,具有两个性质,1.任何一个自然数在数对中都仅出现一次,任意一个b-a的差值也只出现一次,同时知道第n个点对的差值是n;
还有一个相似问题:桌子上有N堆硬币,数量为a1,a2,······an;两个玩家每次可以从任意一堆中取走任意个硬币(>0),最后将硬币取光的玩家胜;
结论:它是先摸者必输当且仅当a1^a2^...^an=0,其中^表示异或(xor)运算;
关于异或运算:
a=a^b^b
可以使用这一位运算性质进行交换操作;
1 struct RESULT 2 { 3 int a,b; 4 }; 5 6 void swap(RESULT &num) 7 { 8 num.a=num.a^num.b; 9 num.b=num.a^num.b; 10 num.a=num.a^num.b; 11 } 12 13 int main( ) 14 { 15 RESULT tmp; 16 tmp.a=1; 17 tmp.b=2; 18 swap(tmp); 19 cout<<tmp.a<<ends<<tmp.b<<endl; 20 return 0; 21 }
标签:style blog http color os 使用 ar strong 2014
原文地址:http://www.cnblogs.com/chengyuz/p/3949231.html