博弈論 取石子遊戲 HDU 2516

2021-08-28 01:11:59 字數 1160 閱讀 4123

題解——列舉一下從1到13左右會發現如果當前是斐波那契數必輸

**: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也是乙個必敗點。

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

#include

#include

#include

#include

#define ll long long

using

namespace

std;

int main()

ans = i;

while(~scanf("%lld",&n)&&n)

if(nbreak;}}

if(flag)

cout

<

cout

<

0;}

HDU 2516 取石子遊戲 (博弈論)

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

博弈論 HDU 2516 取石子遊戲

n 個石子,兩人輪流取.先取者第1次可以取任意多個,但不能全部取完.以後每次取的石子數不能超過上次取子數的2倍。取完者勝.先取者負輸出 second win 先取者勝輸出 first win n 為斐波那契數先手必敗,否則先手必勝 dalao的證明 include include include d...

HDU 2516 取石子遊戲(博弈)

思路 手推了一下,發現n是斐波那契數時是必敗態 includeusing namespace std define ll long long int fact 105 void init int main description 1堆石子有n個,兩人輪流取.先取者第1次可以取任意多個,但不能全部取完...