HDU 2516 取石子游戏 斐波纳契博弈
生活随笔
收集整理的這篇文章主要介紹了
HDU 2516 取石子游戏 斐波纳契博弈
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
斐波納契博弈:
有一堆個數為n的石子,游戲雙方輪流取石子,滿足:
1)先手不能在第一次把所有的石子取完;
2)之后每次可以取的石子數介于1到對手剛取的石子數的2倍之間(包含1和對手剛取的石子數的2倍)。
約定取走最后一個石子的人為贏家,求必敗態。
?
證明 FBI數為必敗局:
1.對于任意一個FBI數 FBI[K]=FBI[K-1]+FBI[K-2],我們可以將FBI[K]看成石子數目分別是FBI[K-1],FBI[K-2]的兩堆(一定可以這樣分,因為FBI[K-1] > FBI[K-2]*2,若先手取的數目大于等于FBI[K-2],則后手可以一次拿完)
2.將FBI[K-2],FBI[K-1],再次拆分,無論先手如何取,后手總能取走最后一個石子
?
證明 非FBI數為必勝局:
1.由齊肯多夫定理知道,任意一個整數,可以被拆分成幾個不連續的FBI數相加的形式:n=FBI(ak)+FBI(ak-1)+FBI(ak-2)+……+FBI(a1)
2.因為式子中的FBI數不連續,所以FBI(a) > 2FBI(a-1)
3.先手取走FBI(a1)個石子,那么后手只能在FBI(a1+1)堆中取,且不能一次性取完。依舊是說對于任意一堆,總是先手取走最后一個石子!
?
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<iostream> #include<algorithm> #define INF 0x3f3f3f3f #define MAXSIZE 100005using namespace std;int fib[MAXSIZE];int Game(int n) {for(int i=1;i<=46;i++){if(fib[i]==n)return 0;}return 1; }int main() {int n;fib[1]=1;for(int i=2;i<=46;i++)fib[i]=fib[i-1]+fib[i-2];while(scanf("%d",&n),n){int op=Game(n);if(op==0)printf("Second win\n");elseprintf("First win\n");}return 0; } View Code?
轉載于:https://www.cnblogs.com/alan-W/p/6286595.html
總結
以上是生活随笔為你收集整理的HDU 2516 取石子游戏 斐波纳契博弈的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 卧室内墙角放置玻璃空花瓶好以吗?
- 下一篇: 家里防盗窗筑鸟巢好吗