[poj2425]A Chess Game_博弈论

A Chess Game poj-2425

题目大意题目链接

注释:略。


想法:这个题就是为什么必须要用记忆化搜索。因为压根就不知道后继是谁。

我们通过SG定理可知:当前游戏的SG值等于所有子游戏的SG的异或和。

我们就可以dp了。

最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 1010 
int sg[N],n,x,ans,m;
int SS[N];
int tot,to[N*N<<1],head[N],nxt[N*N<<1],cnt[N],num;
inline void add(int x,int y) {to[++tot]=y; nxt[tot]=head[x]; head[x]=tot;}
int dfs(int pos)
{
	if(sg[pos]!=-1) return sg[pos];
	bool vis[N];
	for(int i=0;i<n;i++) vis[i]=false;
	for(int i=head[pos];i;i=nxt[i]) vis[dfs(to[i])]=true;
	for(int i=0;;i++) if(!vis[i]) return sg[pos]=i;
}
int main()
{
	while(~scanf("%d",&n))
	{
		memset(sg,-1,sizeof sg);
		memset(head,0,sizeof head);
		memset(cnt,0,sizeof cnt);
		tot=0;
		for(int i=0;i<n;i++)
		{
			scanf("%d",&num);
			for(int j=1;j<=num;j++)
			{
				scanf("%d",&x);
				add(i,x); 
				cnt[x]++;
			}
		}
		for(int i=0;i<n;i++) if(!cnt[i]) sg[i]=dfs(i);
		while(scanf("%d",&m)&&m)
		{
			ans=0;
			for(int i=1;i<=m;i++)
			{
				scanf("%d",&x);
				ans^=sg[x];
			} 
			if(ans) printf("WIN\n");
			else printf("LOSE\n");
		}
	}
}

小结:血泪教训:dfs那个vis必须开局部!!不然搜的时候memset全炸了... ...

posted @ 2018-09-09 20:59  JZYshuraK_彧  阅读(189)  评论(0编辑  收藏  举报