题目链接:http://poj.org/problem?id=2068
两个队伍,每队n人, 一堆石子s个,两队轮流拿,n个数,奇数位是1队,偶数位是2队,数值表示这名选手最多可以拿多少个。然后选手按照顺序交替取石子,求是否必胜。
题目本身不难,关键能不能想到dp[i][j]去表示轮到第i个人拿的时候,有j个石子。
参考了一下大神的博客,才知道这题是dp,看到dp数组就自己可以打了,看来做博弈还是要融会贯通的啊。
#include<vector>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
// 轮到i个人,剩余j的石头
int dp[25][1 << 13 + 1];
int pp[25];
int n, s;
bool dfs(int pos, int remain) {
if(dp[pos][remain] != -1) {
return dp[pos][remain];
}
if(remain == 0) {
return dp[pos][remain] = 1;
}
dp[pos][remain] = 0;
for (int i = 1; i <= pp[pos] && i <= remain; i ++) {
if(!dfs((pos + 1) % n, remain - i)) {
dp[pos][remain] = 1;
}
}
return dp[pos][remain];
}
int main() {
while (scanf("%d", &n) != EOF, n) {
n = n << 1;
scanf("%d", &s);
for (int i = 0; i < n; i ++) {
scanf("%d", pp + i);
}
memset(dp, -1, sizeof(dp));
printf("%d\n", dfs(0, s));
}
return 0;
}