dp[sum][_1][_2][_3][_4][_5][_6] 为某个sg函数的状态 用依次的转移转化胜负状态,感觉对sg函数有更深的理解了
SG函数的代码 dp的代码也类似
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <string>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const double PI = acos(-1.0);
template <class T> inline T MAX(T a, T b){if (a > b) return a;return b;}
template <class T> inline T MIN(T a, T b){if (a < b) return a;return b;}
const int N = 111;
const int M = 11111;
const LL MOD = 1000000007LL;
const int dir[4][2] = {1, 0, -1, 0, 0, -1, 0, 1};
const int INF = 0x3f3f3f3f;
int dp[40][6][6][6][6][6][6];
int sg(int sum, int _1, int _2, int _3, int _4, int _5, int _6)
{
int i, j, k, vis[10];
memset(vis, 0, sizeof(vis));
int &ans = dp[sum][_1][_2][_3][_4][_5][_6];
if (sum == 31)
{
ans = 0;
return 0;
}
if (ans != -1) return ans;
if (_1 > 0 && sum + 1 <= 31)
{
vis[sg(sum + 1, _1 - 1, _2, _3, _4, _5, _6)] = 1;
}
if (_2 > 0 && sum + 2 <= 31)
{
vis[sg(sum + 2, _1, _2 - 1, _3, _4, _5, _6)] = 1;
}
if (_3 > 0 && sum + 3 <= 31)
{
vis[sg(sum + 3, _1, _2, _3 - 1, _4, _5, _6)] = 1;
}
if (_4 > 0 && sum + 4 <= 31)
{
vis[sg(sum + 4, _1, _2, _3, _4 - 1, _5, _6)] = 1;
}
if (_5 > 0 && sum + 5 <= 31)
{
vis[sg(sum + 5, _1, _2, _3, _4, _5 - 1, _6)] = 1;
}
if (_6 > 0 && sum + 6 <= 31)
{
vis[sg(sum + 6, _1, _2, _3, _4, _5, _6 - 1)] = 1;
}
i = 0;
while (vis[i]) i++;
ans = i;
return ans;
}
int main()
{
char str[50];
int num[10];
while (scanf("%s", str) != EOF)
{
int sum = 0, i, j, k, l;
l = strlen(str);
fill(num, num + 7, 4);
for (i = 0; i < l; ++i)
{
sum += str[i] - '0';
if (sum > 31)
{
if (i & 1)
{
printf("%s B\n", str);
}
else
{
printf("%s A\n", str);
}
break;
}
num[str[i] - '0']--;
}
if (sum > 31) continue;
memset(dp, -1, sizeof(dp));
if (sg(sum, num[1], num[2], num[3], num[4], num[5], num[6]) != 0)
{
if (l & 1) printf("%s B\n", str);
else printf("%s A\n", str);
}
else
{
if (l & 1) printf("%s A\n", str);
else printf("%s B\n", str);
}
}
return 0;
}