题意:
多组数据
两人轮流操作,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 10000 using 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"); } }
原文地址:http://blog.csdn.net/vmurder/article/details/42583495