1. 程式人生 > >題解報告:hdu 2516 取石子遊戲(斐波那契博弈)

題解報告:hdu 2516 取石子遊戲(斐波那契博弈)

csdn 數組 pre lse http 根據 代碼 als names

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=2516

Problem Description 1堆石子有n個,兩人輪流取.先取者第1次可以取任意多個,但不能全部取完.以後每次取的石子數不能超過上次取子數的2倍。取完者勝.先取者負輸出"Second win".先取者勝輸出"First win". Input 輸入有多組.每組第1行是2<=n<2^31. n=0退出. Output 先取者負輸出"Second win". 先取者勝輸出"First win". 參看Sample Output. Sample Input 2 13 10000 0 Sample Output Second win Second win First win 解題思路:斐波那契博弈。斐波那契博弈模型,大致上是這樣的:有一堆個數為 n 的石子,遊戲雙方輪流取石子,滿足:

1. 先手不能在第一次把所有的石子取完;
2. 之後每次可以取的石子數介於1到對手剛取的石子數的2倍之間(包含1和對手剛取的石子數的2倍)。
約定取走最後一個石子的人為贏家,求必敗態。
我們簡單舉幾個栗子:

當n=2時,後手必贏

當n=3時,後手必贏

當n=4時,只要先手取1個,剩下3個,無論後手取多少個,先手必贏

當n=5時,①若先手先取1個,剩下4個,此時後手掌握n=4這種局面,則後手必贏;②若先手取2個,根據規則,後手可以一次性取完剩下的3個,則後手必贏;所以先手無論怎麽取,此時後手必贏

當n=6時,先手只要取1個,先手就掌握了n=5這種局面,即先手必贏

當n=7時,先手只要取2個,先手就掌握了n=5這種局面,即先手必贏

當n=8時,①若先手取1個時,後手就掌握了n=7這種局面,即後手必贏;②若先手取2個時,後手就掌握了n=6這種局面,即後手必贏;③若先手取3個,根據規則,後手可以一次性取走剩下的5個,剩下的情況都是後手必贏;所以無論先手怎麽取,此時後手必贏

......

繼續推導下去,我們可以發現,只要n滿足斐波那契數列2,3,5,8,13......,則後手必贏,否則先手必贏。相關證明看這:斐波那契博弈

由於n在int範圍內,且fib[45]剛好超過int範圍,所以fib數組長度只需為44即可。 AC代碼:
 1 #include<bits/stdc++.h>
 2 using namespace
std; 3 int main() 4 { 5 int n,fib[44]={2,3};bool flag; 6 for(int i=2;i<44;++i)//只需枚舉44個fib數即可 7 fib[i]=fib[i-1]+fib[i-2]; 8 while(cin>>n && n){ 9 flag=false; 10 for(int i=0;i<44;++i) 11 if(fib[i]==n){flag=true;break;} 12 if(flag)cout<<"Second win"<<endl;//如果滿足斐波那契數列,則後手必贏 13 else cout<<"First win"<<endl;//否則先手必贏 14 } 15 return 0; 16 }

題解報告:hdu 2516 取石子遊戲(斐波那契博弈)