HDU2516 取石子遊戲 斐波那契博弈

2021-08-10 14:11:19 字數 1697 閱讀 4996

1堆石子有n個,兩人輪流取.先取者第1次可以取任意多個,但不能全部取完.以後每次取的石子數不能超過上次取子數的2倍。取完者勝.先取者負輸出」second

win」.先取者勝輸出」first win」.

輸入有多組.每組第1行是2<=n<2^31. n=0退出.

先取者負輸出」second win」. 先取者勝輸出」first win」. 參看sample output.

2

1310000

0

second win

second win

first win

這是一道fibonacci』s game(斐波那契博弈)

斐波那契博弈模型,大致上是這樣的:

有一堆個數為 n 的石子,遊戲雙方輪流取石子,滿足:

先手不能在第一次把所有的石子取完;

之後每次可以取的石子數介於1到對手剛取的石子數的2倍之間(包含1和對手剛取的石子數的2倍)。 約定取走最後乙個石子的人為贏家,求必敗態。

分析:

n = 2時輸出second;

n = 3時也是輸出second;

n = 4時,第乙個人想獲勝就必須先拿1個,這時剩餘的石子數為3,此時無論第二個人如何取,第乙個人都能贏,輸出first;

n = 5時,first不可能獲勝,因為他取2時,second直接取掉剩下的3個就會獲勝,當他取1時,這樣就變成了n為4的情形,所以輸出的是second;

n = 6時,first只要去掉1個,就可以讓局勢變成n為5的情形,所以輸出的是first;

n = 7時,first取掉2個,局勢變成n為5的情形,故first贏,所以輸出的是first;

n = 8時,當first取1的時候,局勢變為7的情形,第二個人可贏,first取2的時候,局勢變成n為6得到情形,也是第二個人贏,取3的時候,second直接取掉剩下的5個,所以n = 8時,輸出的是second;

…………

從上面的分析可以看出,n為2、3、5、8時,這些都是輸出second,即必敗點,仔細的人會發現這些滿足斐波那契數的規律,可以推斷13也是乙個必敗點。

借助「zeckendorf定理」(齊肯多夫定理):任何正整數可以表示為若干個不連續的fibonacci數之和。n=12時,只要誰能使石子剩下8且此次取子沒超過3就能獲勝。因此可以把12看成8+4,把8看成乙個站,等價與對4進行」氣喘操作」。又如13,13=8+5,5本來就是必敗態,得出13也是必敗態。也就是說,只要是斐波那契數,都是必敗點。

所以我們可以利用斐波那契數的公式:fib[i] = fib[i-1] + fib[i-2],只要n是斐波那契數就輸出second。

所以結論是:只要石子數是斐波那契數,那麼後手必贏

#include 

using

namespace

std;

int f[100];

void init()

int main()

if(flag)puts("first win");

else

puts("second win");

}return

0;}

HDU 2516 取石子遊戲(斐波那契博弈)

本題是傳說中的斐波那契博弈,即 必敗點形成了fibonacci數列,通過找規律就可以看出來的 為何比賽時木有發現 problem description 1堆石子有n個,兩人輪流取.先取者第1次可以取任意多個,但不能全部取完.以後每次取的石子數不能超過上次取子數的2倍。取完者勝.先取者負輸出 sec...

HDU 2516 取石子遊戲(斐波那契博弈)

看這道題之前先看看什麼叫斐波那契博弈 斐波那契博弈 需要知道 zeckendorf定理 齊肯多夫定理 任何正整數可以表示為若干個不連續的fibonacci數之和。總結一下就是如果給定的數是斐波那契數列中的乙個,則先手必敗,否則先手必勝,沒有什麼道理的裸題 include include includ...

取石子遊戲 HDU2516(斐波那契博弈)

題目 problem description 1堆石子有n個,兩人輪流取.先取者第1次可以取任意多個,但不能全部取完.以後每次取的石子數不能超過上次取子數的2倍。取完者勝.先取者負輸出 second win 先取者勝輸出 first win input 輸入有多組.每組第1行是2 n 2 31.n ...