题目链接:点击这里
题意:有1,2,3,4,5,6各四张牌,AB轮流出牌,谁先使得总和超过31就输.告诉你已经出牌的序列,求最优策略下谁赢.
经典的博弈题了.先把游戏结束的状态挖出来,然后记忆化搜索一遍即可.
#include <bits/stdc++.h>
#define Clear(x,y) memset (x,y,sizeof(x))
#define FOR(a,b,c) for (int a = b; a <= c; a++)
#define REP(a,b,c) for (int a = b; a >= c; a--)
#define fi first
#define se second
#define pii pair<int, int>
#define pli pair<long long, int>
#define pb push_back
#define mod 1000000007
using namespace std;
#define maxn 1005
int dp[5][5][5][5][5][5];//6张牌的状态
void dfs (int x, int y, int z, int a, int b, int c) {
int num = x+y+z+a+b+c;
int cnt = 0;//后继状态有多少个1
int tot = 0;//后继状态总数
if (x < 4) {
if (dp[x+1][y][z][a][b][c] == -1) dfs (x+1, y, z, a, b, c);
cnt += dp[x+1][y][z][a][b][c];
tot++;
}
if (y < 4) {
if (dp[x][y+1][z][a][b][c] == -1) dfs (x, y+1, z, a, b, c);
cnt += dp[x][y+1][z][a][b][c];
tot++;
}
if (z < 4) {
if (dp[x][y][z+1][a][b][c] == -1) dfs (x, y, z+1, a, b, c);
cnt += dp[x][y][z+1][a][b][c];
tot++;
}
if (a < 4) {
if (dp[x][y][z][a+1][b][c] == -1) dfs (x, y, z, a+1, b, c);
cnt += dp[x][y][z][a+1][b][c];
tot++;
}
if (b < 4) {
if (dp[x][y][z][a][b+1][c] == -1) dfs (x, y, z, a, b+1, c);
cnt += dp[x][y][z][a][b+1][c];
tot++;
}
if (c < 4) {
if (dp[x][y][z][a][b][c+1] == -1) dfs (x, y, z, a, b, c+1);
cnt += dp[x][y][z][a][b][c+1];
tot++;
}
if (num%2 == 0) {//A先手
if (cnt > 0) dp[x][y][z][a][b][c] = 1;
else dp[x][y][z][a][b][c] = 0;
}
else {//B先手
if (cnt == tot) dp[x][y][z][a][b][c] = 1;
else dp[x][y][z][a][b][c] = 0;
}
}
int main () {
//freopen ("more.in", "r", stdin);
memset (dp, -1, sizeof dp);
for (int x = 0; x <= 4; x++) for (int y = 0; y <= 4; y++) for (int z = 0; z <= 4; z++) {
for (int a = 0; a <= 4; a++) for (int b = 0; b <= 4; b++) for (int c = 0; c <= 4; c++) {
int num = x+y+z+a+b+c;
int sum = x*1+y*2+z*3+a*4+b*5+c*6;
if (sum > 31) {
if (num%2 == 0) dp[x][y][z][a][b][c] = 1;
else dp[x][y][z][a][b][c] = 0;
}
}
}
dfs (0, 0, 0, 0, 0, 0);
int tmp[7];
char s[233];
while (cin >> s) {
int n = strlen (s);
Clear (tmp, 0);
for (int i = 0; i < n; i++) {
tmp[s[i]-'0']++;
}
int ans = dp[tmp[1]][tmp[2]][tmp[3]][tmp[4]][tmp[5]][tmp[6]];
printf ("%s %s\n", s, ans ? "A" : "B");
}
return 0;
}