POJ1143(博弈+记忆化搜索)


#include<iostream>
#include<string>
#include<iomanip>
#include<algorithm>
#include <cstdio>
#include <queue>
#include <cstring>
#include <cstdlib>
using namespace std;

int dp[2000000];
//int hash[]={0,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,
		        //8192,16384,32768,65536,131072,262144,524288};

bool dfs(int state)
{
	if (dp[state]!=-1)
		return dp[state];
	if (!state)
	{
		dp[state]=0;
		return false;
	}
  int i,j;
  bool flag=false;
  for (i=2;i<=20;i++)
  	if ((state&1<<(i-1))!=0)
  	{
  		int temp_state=state;
  		temp_state&=~(1<<(i-1));
  		for (j=2;i+j<=20;j++)
  			if ((temp_state&1<<(j-1))==0)
  				temp_state&=~(1<<(i+j-1));
  		if (!dfs(temp_state))
  		{
  		  flag=true;
  		  break;
  		}
  	}
  if (flag)
  {
  	dp[state]=1;
  	return true;
  }
  dp[state]=0;
  return false;
}

int main()
{
	int n;
	int T=0;
	memset(dp,-1,sizeof(dp));
	while (1)
	{
		T++;
		scanf("%d",&n);
		if (!n) break;
		int A[20];
		int i,j;
		int state=0;
		for (i=0;i<n;i++)
		{
			scanf("%d",&A[i]);
			state|=1<<(A[i]-1);
		}
		int ans[20];
		int counter=0;
    for (i=2;i<=20;i++)
    	if ((state&1<<(i-1))!=0)
    	{
    		int temp_state=state;
    		temp_state&=~(1<<(i-1));
    		for (j=2;i+j<=20;j++)
    			if ((temp_state&1<<(j-1))==0)
    				temp_state&=~(1<<(i+j-1));
    		if (!dfs(temp_state))
    		  ans[counter++]=i;
    	}
    printf("Test Case #%d\n",T);
    if (counter)
    {
      printf("The winning moves are:");
      for (i=0;i<counter;i++)
      	printf(" %d",ans[i]);
      printf("\n");
    }
    else
      printf("There's no winning move.\n");
    printf("\n");
	}
}


你可能感兴趣的:(POJ1143(博弈+记忆化搜索))