HDU 2516 取石子游戏 斐波纳契博弈
斐波納契博弈:
有一堆個數(shù)為n的石子,游戲雙方輪流取石子,滿足:
1)先手不能在第一次把所有的石子取完;
2)之后每次可以取的石子數(shù)介于1到對手剛?cè)〉氖訑?shù)的2倍之間(包含1和對手剛?cè)〉氖訑?shù)的2倍)。
約定取走最后一個石子的人為贏家,求必敗態(tài)。
?
證明 FBI數(shù)為必敗局:
1.對于任意一個FBI數(shù) FBI[K]=FBI[K-1]+FBI[K-2],我們可以將FBI[K]看成石子數(shù)目分別是FBI[K-1],FBI[K-2]的兩堆(一定可以這樣分,因為FBI[K-1] > FBI[K-2]*2,若先手取的數(shù)目大于等于FBI[K-2],則后手可以一次拿完)
2.將FBI[K-2],FBI[K-1],再次拆分,無論先手如何取,后手總能取走最后一個石子
?
證明 非FBI數(shù)為必勝局:
1.由齊肯多夫定理知道,任意一個整數(shù),可以被拆分成幾個不連續(xù)的FBI數(shù)相加的形式:n=FBI(ak)+FBI(ak-1)+FBI(ak-2)+……+FBI(a1)
2.因為式子中的FBI數(shù)不連續(xù),所以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?
轉(zhuǎn)載于:https://www.cnblogs.com/alan-W/p/6286595.html
總結(jié)
以上是生活随笔為你收集整理的HDU 2516 取石子游戏 斐波纳契博弈的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 卧室内墙角放置玻璃空花瓶好以吗?
- 下一篇: ReactiveNative学习之Dif