Nim(poj 2068)

11 篇文章 0 订阅

题目:点击打开链接

有两个队伍,队员交叉坐,轮流从一堆石子中取石子,每个人都规定了去石子的最大数量,取到最后一个石子的人所属的队伍输。问第一个队伍是否会赢。

通过求sg函数来判断,sg[i][j]表示当第i个人取是还有j个石子的情况。先初始化,无论是谁,是要面对1个石子的情况,那么肯定输,所以sg[i][1] = 0(或者谁面对石子数是0的情况谁就赢即 sg[i][0] = 1)。最终我们要判断的是sg[1][sum]的值,也就从此递归,有一个地方我一开始没有考虑到的就是递归的人数如果大于所有的人数,那么就要回到第一个队员开始再一轮的取石子,所以getsg函数中第一二两句就是这个作用……剩下的就是求SG函数的过程了。看其他人写的,这种方法貌似也是动态规划。


#include <stdio.h>
#include <string.h>
 
int s;
int a[25];
int sg[25][9000];//sg[i][j]表示第i个人拿的时候还剩下j个石子 

int getsg(int m, int n)
{
	if(m > s * 2)//开始一直没加这个条件,当一轮取完之后,石子还没有被取尽,那么就要继续从第一个开始循环 
		return getsg(m - s * 2, n);
	if(sg[m][n] != -1)
		return sg[m][n];
	int i;
	bool hash[110];
	memset(hash, 0, sizeof(hash));
	for(i = 1; i <= a[m] && n - i > 0; i++)
		hash[getsg(m + 1, n - i)] = 1;
	for(i = 0; i < 100; i++)
		if(hash[i] == 0)
			break;
	return sg[m][n] = i;
}

int main (void)
{
	while(scanf("%d", &s) != EOF)
	{
		if(s == 0)
			break;
		int sum, i;
		scanf("%d", &sum);
		for(i = 1; i <= 2 * s; i++)
			scanf("%d", &a[i]);
		memset(sg, -1, sizeof(sg));
		for(i = 0; i <= s * 2; i++)
		{
			sg[i][1] = 0;//轮到某个人取但只剩下1个那么必输 
		}
		int ok = getsg(1, sum);
		if(ok == 0)
			printf("0\n");
		else
			printf("1\n");
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Fibonacci Nim是一个游戏,与Fibonacci数列有密切关系。根据引用\[1\]的描述,先手胜利的条件是硬币数量不是Fibonacci数。换句话说,必败态构成Fibonacci数列。如果硬币数量是Fibonacci数,那么后手必胜。这是因为先手只能在Fibonacci数列中的一堆中取硬币,而后手可以根据上一个问题的子问题的解决方案取走该堆最后一枚硬币,从而剩下的一堆硬币也可以如此拆分,使得先手必败。如果硬币数量不是Fibonacci数,根据Zeckendorf定理,可以将硬币数量表示为不连续的Fibonacci数之和。在这种情况下,先手可以先取完最小的一堆硬币,而后手无法取完剩下的最少的一堆硬币,从而面对必败态。因此,先手可以在每一堆中取到最后一枚硬币,从而获胜。\[2\]根据引用\[3\]中的代码,可以通过判断硬币数量是否是Fibonacci数来确定先手或后手的胜利。如果硬币数量是Fibonacci数,输出"Second win";如果不是,输出"First win"。 #### 引用[.reference_title] - *1* *3* [斐波那契博弈](https://blog.csdn.net/iteye_6233/article/details/82396581)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Fibonacci Nim(斐波那契尼姆)游戏](https://blog.csdn.net/darren0424/article/details/101639021)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值