【POJ2068】Nim DP博弈

来源:互联网 发布:如何查看淘宝注册时间 编辑:程序博客网 时间:2024/04/30 13:07

题意:

多组数据

两人轮流操作,n轮一循环,给出总石子数和这n轮每次两人能取的石子上限(下限为1)。

取到最后一颗者输。


比如

3 97 8 7 6 5 4 3

表示一循环有三轮,

可取的个数为:

第一轮 先手8 后手7

第二轮 先手6 后手5

第三轮 先手4 后手3

然后三轮每取完的话就进入下次循环。


数据范围自己看去吧。



题解:

DP就好。

博弈性质:如果当前状态对手怎么走都败,此状态就是胜,不然就是负。

记忆化搜索一下水过。


代码:

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define N 30#define M 10000using namespace std;int f[N][M],a[N],n,m;// 1为败int dfs(int x,int y){if(f[x][y]+1)return f[x][y];for(int i=max(0,y-a[x]);i<y;i++)// 枚举剩多少石子if(!dfs((x+1)%n,i))return f[x][y]=1;return f[x][y]=0;}int main(){//freopen("test.in","r",stdin);while(scanf("%d",&n),n){n<<=1,scanf("%d",&m);for(int i=0;i<n;i++)scanf("%d",&a[i]);memset(f,-1,sizeof(f));for(int i=0;i<n;i++)f[i][0]=1;if(dfs(0,m))puts("1");else puts("0");}}



0 0