POJ 2068 Nim(博弈论)
【题目链接】 http://poj.org/problem?id=2068
【题目大意】
给出两队人,交叉放置围成一圈,每个人能取的石子数有个上限,各不相同
轮流取石头,取到最后一块石头的队伍算输,问哪个队伍能赢
【题解】
用dp[i][j]记录第i个人取石头时候还有j个石头的状态,
显然j==0时候为必胜态,我们对每个状态搜索后继状态,如果能导向必败态则为必胜态,
否则必败,记忆化搜索即可。
【代码】
#include <cstdio> #include <cstring> using namespace std; int sg[20][8193],n,s,a[20]; int SG(int id,int r){ if(sg[id][r]!=-1)return sg[id][r]; if(r==0)return sg[id][r]=1; sg[id][r]=0; for(int i=1;i<=a[id]&&i<=r;i++){ if(!SG((id+1)%(2*n),r-i))sg[id][r]=1; }return sg[id][r]; } int main(){ while(~scanf("%d",&n),n){ scanf("%d",&s); for(int i=0;i<2*n;i++)scanf("%d",&a[i]); memset(sg,-1,sizeof(sg)); printf("%d\n",SG(0,s)); }return 0; }
愿你出走半生,归来仍是少年