威佐夫博弈:
有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜。
我们用(ak,bk)(ak<=bk,k=0,1,2,3...n)表示两堆物品的数量,并将这种形式记为局势。
如果甲面对局势(0,0),说明甲输了,我们把这种情况叫做奇异局势。
现在的问题我给你一个局势(a,b),我们怎么判断它是不是奇异局势呢?
判断公式为:
ak=[k(1+√5)/2](向下取整),
bk=ak+k(k=0,1,2,…,n,[]:取整-高斯函数).
所以令:k=b-a;那么如果:a=[(b-a)(1+√5)/2],那么这个局势为奇异局势。
如果面对非奇异局势,先拿者必胜;反之,则后拿者取胜。
例题:
POJ1067
var
a,b :longint;
function work(a,b:longint):integer;
var
k:longint;
begin
if (a>b) then
begin
k:=a;a:=b;b:=k;
end;
//
k:=b-a;
if (a=trunc(k*(sqrt(5)+1)/2)) then exit(0);//运用公式判断
exit(1);
end;
begin
read(a,b);
while not EOF do
begin
writeln(work(a,b));
read(a,b);
end;
end.<span style="color:#ca0000;">
</span>
我们知道a0=b0=0,ak是没有在前面出现过的最小自然数,bk=ak+k,由上面的代码可以知道前几组的奇异局势:
(0,0)、(1,2)、(3,5)、(4,7)、(6,10)、(8,1)、(9,15)、(11,18)、(12,20)。
奇异局势的三个性质为:
(1)、任何自然数都包含在一个且仅有一个奇异局势中。
原理:ak是没有在前面出现过的最小自然数,所以ak>ak-1,bk=ak+k>ak-1+(k-1)=bk-1>ak-1。
(2)、任意操作都可将奇异局势变为非奇异局势。
原理:若是只改变奇异局势(ak,bk)中的一个分量,由于另一个分量不可能存在于其他的奇异局势中,所以改变后一定是非奇异局势,
如果使(ak,bk)的两个分量同时减少,则由于其差(k)不变,但是a变了,所以一定是非奇异局势。
(3)、采用适当的方法,可以将非奇异局势变为奇异局势。
必败态的公式求解过程,需用到贝亚蒂定理:
若p,q∈R+(正实数集),且p,q为无理数,使得1/p+1/q=1,
定义集合(贝亚蒂序列)P={ [np]:n∈Z+ },Q={ [nq]:n∈Z+ },
则P 和Q 构成正整数集的一个分划:P∩Q=空集,PUQ=Z+,
也就是说:
如果两个正无理数的倒数之和是1,
则任何正整数都可刚好以一种形式表示为不大于其中一个无理数的正整数倍的最大整数。
可知:
ak,bk刚好为贝亚蒂序列,
那么我可以令ak=[kp],bk=[kq],且1/p+1/q=1。
由于bk=ak+k=[kp]+k=[k(p+1)]=[kq],所以q=p+1,
则有:1/p+1/(p+1)=1,可以求出p=(√5+1)/2。这就是必败态的通向公式:ak=[k(1+√5)/2]。
2)给你一个局面,让你求先手输赢,假设先手赢的话输出他第一次的取法。
首先讨论在两边同时取的情况,
很明显两边同时取的话,不论怎样取他的差值是不会变的,
那么我们可以根据差值计算出其中的小的值,然后加上差值就是大的一个值,
当然能取的条件是求出的最小的值不能大于其中小的一堆的石子数目。
如果在一堆中取的话,可以取任意一堆,那么其差值也是不定的,
但是我们可以枚举差值,差值范围是0--- 大的石子数目,
然后根据上面的理论判断满足条件的话就是一种合理的取法。
——by Eirlys
转载请注明出处=w=