斐波那契博弈

规则: 有n个石子,先手可以取[1,n)个石子,而后的人至多能取上一个取石子数的两倍,即[1,2*x]。取完胜
结论: 若n为斐波那契数,则先手必败,否则必胜
证明:
数学归纳法:
记f[i]为斐波那契数列
若n = f[0] = 2,显然先手必败
设n <= f[k]时,先手必败
当n = f[k+1]时
f[k+1] = f[k] + f[k-1]
对于f[k-1]这一堆石子,由于f[k-1] < f[k],所以这一堆石子一定由后手取完
现在对于f[k]这一堆,我们只要保证先手无法一口气取完,就可保证这一堆也一定由后手取完,即后手胜利
证明在f[k-1]这一堆石子取完后f[k]无法被一口气取完:
对于f[k-1]这一堆石子,后手至多取 2 3 \frac{2}{3} 32f[k-1],我们只要证明 2 3 f [ k − 1 ] \frac{2}{3}f[k-1] 32f[k1] < 1 2 f [ k ] \frac{1}{2}f[k] 21f[k]即可
即4f[k-1] < 3f[k] = 3(f[k-1]+f[k-2]) => f[k-1] < 3f[k-2],显然成立

/*
有n个石子
先手可以取[1,n)个石子,而后的人至多能取上一个取石子数的两倍,取完胜
若n为斐波那契数,则先手必败,否则必胜
*/
#include <cstdio>
#include <set>
using namespace std;

int main()
{
	set<int> s;
	s.insert(2);
	s.insert(3);
	int temp1 = 2;
	int temp2 = 3;
	while ( temp1 + temp2 > 0 )
	{
		int t = temp1 + temp2;
		s.insert(t);
		temp1 = temp2;
		temp2 = t;
	}
	int n;
	while( scanf("%d",&n) && n != 0 )
	{
		if( s.find(n) != s.end() ) printf("Second win\n");
		else printf("First win\n");
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值