AtCoder Beginner Contest 278-F

F - Shiritori

题解:n最大16,所以可以状态压缩,相当于n个点的带权有向图。
dp[i][j]表示当前状态为i,j结尾的情况,其中dp[i][j]=1表示First赢,0为second赢,如果一个字符串s[i],第一个字符为j,那么如果dp[k][s[i].back()]为1那么,dp[i][j]为0,反之亦然,其中最后的状态,就是dp[(1<<n)-1][j]肯定为1,因为First可以选择直接从这个状态开始。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5;
const ll mod=1e9+7;
typedef pair<ll,ll> pll;
#define endl '\n'
ll n;
string s[N];
ll dp[1<<16][30];
signed main(){
  ios::sync_with_stdio(false);
  cin.tie(0);cout.tie(0);
  ll n;cin>>n;
  for(ll i=0;i<n;i++) cin>>s[i];
  for(ll i=(1<<n)-1;i;i--){
    for(ll k=0;k<26;k++){
      ll pt=1;
      for(ll j=0;j<n;j++){
        if((1<<j)&i) continue;//判断当前状态中包不包含这个字符串
        if(s[j][0]!=k+'a') continue;//判断能收尾接上
        if(dp[i|(1<<j)][s[j].back()-'a']){//如果为1便是0
          pt=0;break;
        }
      }
      dp[i][k]=pt;
    }
  }
  for(ll i=0;i<n;i++){
    if(dp[1<<i][s[i].back()-'a']){
      cout<<"First"<<endl;return 0;
    }
  }
  cout<<"Second"<<endl;
}
posted @ 2022-11-21 13:05  HHzp  阅读(53)  评论(0编辑  收藏  举报