吃糖果是永恒不变的话题(博弈论)(北理16校赛)

时间限制1秒 内存限制64M

题目描述:

        Teresa 和 Eureka 玩游戏,有n个糖果 ( 1 <= n <= 1000000 且n为奇数 ) ,两人轮流取糖果吃,可以吃1、2、3个糖果,不能不吃,谁最后总共吃了奇数块糖果就算赢,输的那一方要请赢的人看愤怒的小鸟大电影,假设两人像PQ那样机智(咦PQ是谁?喷泉?),问对于任意合法的 n ,先手能否胜利?


输入格式:

        一个整数T,代表用例组数。

        每组用例一行,一个整数 n ( 1 <= n <= 1000000 且n为奇数 ) ,表示初始有 n 个糖果。


输出格式:

        对于每组用例,若先手必胜输出“first win”,否则输出“first lost”。


样例输入:

        3

        1

        3

        5


样例输出:

        first win

        first win

        first lost


题目大意:

       有一堆奇数个糖果,每个人可以选择拿1,2,3个,最后有奇数个糖果的获胜,问有没有先手必胜策略

解题思路:

       dp[i][j]为还剩i个糖果时,手里有奇数或者偶数(j=1奇,0偶)是否有必胜策略(1有,0无)

      dp[i][j]=sigema(dp[i-k][对手奇偶]==0)>0(k=1,2,3)就是说在自己可以取到的状态里有一个是对手的必败态,自己就必胜,否则自己必败


#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <cmath>
#include <map>
#include <queue>
#include <string>
#include <set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int INF=0x3f3f3f3f;
#define CLR0(a) (memset(a,0,sizeof(a)))
#define CLR1(a) (memset(a,-1,sizeof(a)))
#define CLRf(a) (memset(a,0x3f,sizeof(a)))
const int maxn=0;
const int maxm=0;
int dp[1000050][2];
int main()
{
	dp[0][0]=0;
	dp[0][1]=1;
	dp[1][0]=1;
	dp[1][1]=0;
	dp[2][0]=1;
	dp[2][1]=1;
	for(int i=3;i<=1000000;i++)
	{
		int op=!(i%2);
		for(int j=1;j<=3;j++)
		{
			if(dp[i-j][op]==0)
			{
				dp[i][0]=1;
				break;
			}
		}
		op=!op;
		for(int j=1;j<=3;j++)
		{
			if(dp[i-j][op]==0)
			{
				dp[i][1]=1;
				break;
			}
		}
		
	}
	int n;
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		printf("first %s\n",dp[n][0]?"win":"lost");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值