【POJ】【2068】Nim
博弈论/DP
这是Nim?这不是巴什博奕的变形吗……
我也不会捉啊,不过一看最多只有20个人,每人最多拿16个石子,总共只有8196-1个石子,范围好像挺小的,嗯目测暴力可做。
so,记忆化搜索直接水过去了……
出口应该很好判断:当前只有一个石子的时候输,石子数<=m[i]+1则赢(保证拿完后只给对方留一个)
1 Source Code 2 Problem: 2068 User: sdfzyhy 3 Memory: 1416K Time: 32MS 4 Language: G++ Result: Accepted 5 6 Source Code 7 8 //POJ 1000 9 #include<cmath> 10 #include<queue> 11 #include<vector> 12 #include<string> 13 #include<cstdio> 14 #include<cstring> 15 #include<cstdlib> 16 #include<iostream> 17 #include<algorithm> 18 #define rep(i,n) for(int i=0;i<n;++i) 19 #define F(i,j,n) for(int i=j;i<=n;++i) 20 #define D(i,j,n) for(int i=j;i>=n;--i) 21 using namespace std; 22 23 int getint(){ 24 int r=0,c=1; char ch=getchar(); 25 for(;!isdigit(ch);ch=getchar()) if (ch=='-') c=-1; 26 for(;isdigit(ch);ch=getchar()) r=r*10+ch-'0'; 27 return r*c; 28 } 29 const int N=100010,INF=~0u>>2; 30 const double eps=1e-9; 31 /******************template***********************/ 32 #define debug 33 int n,m,a[25]; 34 bool vis[25][8500],dp[25][8500]; 35 bool f(int x,int y){ 36 if (vis[x][y]) return dp[x][y]; 37 vis[x][y]=1; 38 if (y==1) return dp[x][y]=0; 39 if (y<=a[x]+1) return dp[x][y]=1; 40 41 int next; 42 if (x==n*2) next=1; 43 else next=x+1; 44 F(i,1,a[x]) if (f(next,y-i)==0) return dp[x][y]=1; 45 return dp[x][y]=0; 46 } 47 48 int main(){ 49 #ifndef ONLINE_JUDGE 50 freopen("input.txt","r",stdin); 51 freopen("output.txt","w",stdout); 52 #endif 53 while(scanf("%d",&n)!=EOF && n){ 54 m=getint(); 55 F(i,1,n<<1) a[i]=getint(); 56 memset(vis,0,sizeof vis); 57 memset(dp,0,sizeof (dp)); 58 printf("%d\n",f(1,m)); 59 // F(i,1,n<<1) F(j,1,m) printf("f(%d,%d)=%d\n",i,j,dp[i][j]); 60 } 61 return 0; 62 }