codeforces 38F 记忆化搜索
题解:
暴搜即可,注意优先级;
1.先要胜利
2.其次要先自己的分数高
3.再其次要对手的分数低
#include<bits/stdc++.h> #define ll long long #define ull unsigned long long #define fi first #define se second #define mp make_pair #define pii pair<ll,ll> #define all(x) x.begin(),x.end() #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define rep(ii,a,b) for(int ii=a;ii<=b;++ii) #define per(ii,a,b) for(int ii=b;ii>=a;--ii) #pragma GCC optimize("Ofast") using namespace std; const int maxn=3e5+10,maxm=11; int casn,n,m; ll k; struct node{int a,b,flag;}; unordered_map<ull> ck; unordered_map<ull,int> cnt; unordered_map<ull,node> dp; ull pw[40]; node dfs(ull now,int sum,int x,int len,string s=""){ if(dp.count(now)) return dp[now]; node mx={0,0,0}; rep(i,1,26){ ull to=now*29ull+i; if(ck.count(to)){ node tmp=dfs(to,sum+i,max(i,x),len+1,s+char('a'+i-1)); swap(tmp.a,tmp.b); tmp.flag^=1; tmp.a+=(sum+i)*max(i,x)+cnt[to]; if(mx.flag<tmp.flag) mx=tmp; else if(tmp.flag==mx.flag&&mx.a<tmp.a) mx=tmp; else if(tmp.flag==mx.flag&&tmp.a==mx.a&&mx.b>tmp.b) mx=tmp; } to=i*pw[len]+now; if(ck.count(to)){ node tmp=dfs(to,sum+i,max(i,x),len+1,char('a'+i-1)+s); swap(tmp.a,tmp.b); tmp.flag^=1; tmp.a+=(sum+i)*max(i,x)+cnt[to]; if(mx.flag<tmp.flag) mx=tmp; else if(tmp.flag==mx.flag&&mx.a<tmp.a) mx=tmp; else if(tmp.flag==mx.flag&&tmp.a==mx.a&&mx.b>tmp.b) mx=tmp; } } return dp[now]=mx; } int main(){ IO; pw[0]=1; rep(i,1,32) pw[i]=pw[i-1]*29; cin>>n; rep(i,1,n){ set<ull> vis; string s;cin>>s; int len=s.size(); rep(i,0,len-1){ ull t=0; rep(j,i,len-1){ t=t*29+s[j]-'a'+1; vis.insert(t); } } for(auto i:vis) ck.insert(i),++cnt[i]; } auto ans=dfs(0,0,0,0); if(ans.flag) cout<<"First\n"; else cout<<"Second\n"; cout<<ans.a<<' '<<ans.b<<endl; }