链接
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2484
题解
f
(
i
,
j
,
k
)
f(i,j,k)
f(i,j,k)表示模
3
3
3的余数为
0
,
1
,
2
0,1,2
0,1,2的数字分别剩下
i
,
j
,
k
i,j,k
i,j,k个的时候,是否必胜
然后
d
p
dp
dp转移下就好了
这样看似时空复杂度会炸掉,实则不会,因为
i
+
j
+
k
≤
1000
i+j+k \leq 1000
i+j+k≤1000,因此当
i
=
j
=
k
=
33
i=j=k=33
i=j=k=33的时候
i
j
k
ijk
ijk才会取到最大值
35937
35937
35937,即使我每次都
d
p
dp
dp也不会超时,空间的问题找
m
a
p
map
map来解决下就好了
代码
//博弈论、DP
#include <bits/stdc++.h>
#define ll long long
#define v(a,b,c) (a*1002001ll+b*1001ll+c)
using namespace std;
map<ll,bool> f;
bool dfs(ll a, ll b, ll c)
{
if(a==0 and b==0 and c==0)return 0;
if(f.find(v(a,b,c))!=f.end())return f[v(a,b,c)];
bool ans=0;
if(a>0 and !dfs(a-1,b,c))ans=1;
if(b>0 and (b+2)%3==c%3 and !dfs(a,b-1,c))ans=1;
if(c>0 and b%3==(c+2)%3 and !dfs(a,b,c-1))ans=1;
f[v(a,b,c)]=ans;
return ans;
}
char s[10000];
ll N;
int main()
{
ll i, c[3], kase, T, len;
scanf("%lld",&T);
for(kase=1;kase<=T;kase++)
{
printf("Case %lld: ",kase);
scanf("%s",s+1), len=strlen(s+1);
c[0]=c[1]=c[2]=0;
for(i=1;i<=len;i++)c[(s[i]-48)%3]++;
if(dfs(c[0],c[1],c[2]))printf("S\n");
else printf("T\n");
}
return 0;
}