题目链接:这里
题意:三堆石头,每次从一堆中取走若干,或者从两堆中取走相同的数量 ,最后取的人胜。
解法:博弈DP,dp[i][j][k]表示三堆石头分别为i,j,k状态时候是否为必胜。
之后便是N,P态的转换,成必败态能到达的一定是必胜态。不能用记忆化搜索,常数太大,会TLE。而且还卡内存,不能用int,要用bool型。
//ZOJ 3057 博弈DP
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
bool dp[301][301][301] = {0};
int main()
{
for(int i = 0; i <= 300; i++){
for(int j = 0; j <= 300; j++){
for(int k = 0; k <= 300; k++){
if(!dp[i][j][k]){
for(int r=1; r+i<=300; r++) dp[i+r][j][k] = 1;
for(int r=1; r+j<=300; r++) dp[i][j+r][k] = 1;
for(int r=1; r+k<=300; r++) dp[i][j][k+r] = 1;
for(int r=1; r+i<=300&&r+j<=300; r++) dp[i+r][j+r][k] = 1;
for(int r=1; r+i<=300&&r+k<=300; r++) dp[i+r][j][k+r] = 1;
for(int r=1; r+j<=300&&r+k<=300; r++) dp[i][j+r][k+r] = 1;
}
}
}
}
int a, b, c;
while(scanf("%d%d%d", &a,&b,&c)!=EOF){
printf("%d\n", dp[a][b][c]);
}
}