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;
}

猜你喜欢

转载自www.cnblogs.com/nervendnig/p/11252338.html
今日推荐