本代码在 ABC343G 以过,这一题仅仅添加anss数组
不知道哪错了?
玄关!!
// LUOGU_RID: 149343750
// Author: gsczl71
// Copyright (c) 2024 gsczl71 All rights reserved.
#include<bits/stdc++.h>
#define ll long long
#define i128 __int128
#define ull unsigned long long
#define pii pair<int,int>
#define pll pair<long long, long long>
#define fs first
#define sc second
#define endl '\n'
#define debug puts("AK IOI")
#define re register
#define pb push_back
#define mem(a,x) memset((a),(x),sizeof(a))
#define vi vector<int>
#define pq priority_queue
using namespace std;
#define int long long
const int mod = 1e9+7;
//const int mod = 998244353;
const int inf = 0x3f3f3f3f,N =15,M = 205,K = 3000+5;
const long long linf = 0x3f3f3f3f3f3f3f3f;
string s[N];
vector<pii> mp[N];
int nxt[M];int n;
int dis[N][N];
int vis[N][N];
void init(){
for(int i = 1;i <= n;i++) dis[0][i] = s[i].size();
for(int i = 1;i <= n;i++){
for(int j = 1;j <= n;j++){
if(i!=j){
string ans = s[i] + s[j];
int l2=ans.size();ans = ' '+ans;
memset(nxt,0,sizeof nxt);
for(int i = 2,j = 0;i <= l2;++i){
while(j&&ans[i] != ans[j+1])j=nxt[j];
if(ans[i]==ans[j+1]) ++j;
nxt[i]=j;
}int k = l2;while((nxt[k] > (int)s[i].size() || nxt[k] > (int)s[j].size())) k = nxt[k];
dis[j][i]=s[j].size()-nxt[k];
// cout<<j<<" "<<i<<" "<<s[j].size()-nxt[k]<<endl;
// dis[i][j] i 再 j 后面
}
}
}for(int i = 1;i <= n;i++){
for(int j = 1;j <= n;j++){
if(i!=j){
int cnt=0;
string s2 = s[j];
string s1 = s[i];
int l2=s[j].size();
int l1=s[i].size();
memset(nxt,0,sizeof nxt);
s2=' '+s2;s1=' '+s1;
for(int i = 2,j = 0;i <= l2;++i){
while(j&&s2[i] != s2[j+1])j=nxt[j];
if(s2[i]==s2[j+1]) ++j;
nxt[i]=j;
}
for(int i = 1,j = 0;i <= l1;++i){
while(j && s1[i] != s2[j+1])j=nxt[j];
if(s1[i]==s2[j+1]) ++j;
if(j==l2) cnt++,j=nxt[j];
}
if(cnt)vis[j][i]=1;
// vis[i][j] 表示 i 再 j 中
}
}
}
}int dp[1ll<<(N)][N];
string anss[1ll<<(N)][N];
void solve(){
// cout<<(1<<22)*400;
cin >> n;
for(int i = 1;i <= n;i++){
cin >> s[i];
}init();
memset(dp,0x3f,sizeof dp);
for(int i = 1;i <= n;i++){
dp[(1ll<<i)][i] = s[i].size();
anss[(1ll<<i)][i] = s[i];
}
for(int z = 1;z <= (1ll<<(n+1))-2;z++){//状态
for(int i = 1;i <= n;i++) {
if(!((1ll<<i) & z)){
//包含 的 转移
int flag=0;
for(int j = 1;j <= n;j++){
// j -> i
if((1<<j)&z){
if(vis[i][j]){
flag=1;
break;
}
}
}
if(flag)for(int j = 1;j <= n;j++) if((1ll<<j)&z) {
if(dp[z|(1ll<<i)][j] > dp[z][j] || (dp[z|(1ll<<i)][j] == dp[z][j] && anss[z|(1ll<<i)][j] > anss[z][j])) dp[z|(1ll<<i)][j] = dp[z][j],anss[z|(1ll<<i)][j] = anss[z][j];
}
// 接后面
for(int j = 1;j <= n;j++){
// j -> i
if((1ll<<j)&z){
string now = anss[z][j];
for(int k = (int)s[i].size() - dis[i][j];k < (int)s[i].size();k++){
now += s[i][k];
}
if(dp[z|(1<<i)][i] > dp[z][j] + dis[i][j] || (dp[z|(1<<i)][i] == dp[z][j] + dis[i][j] && (anss[z|(1<<i)][i] > now))){
dp[z|(1<<i)][i] = dp[z][j] + dis[i][j];
anss[z|(1<<i)][i] = now;
// cout<<i<<" "<<j << dis[i][j]<<endl;
}
}
}
}
}
}
int minn = 1e9;
for(int i = 1;i <= n;i++){
minn = min(minn,dp[(1ll<<(n+1))-2][i]);
}
set<string> st;
for(int i = 1;i <= n;i++){
if(minn == dp[(1ll<<(n+1))-2][i] && (int)anss[(1ll<<(n+1))-2][i].size() == dp[(1ll<<(n+1))-2][i]){
st.insert(anss[(1ll<<(n+1))-2][i]);
}
}
cout<<*st.begin();
}
signed main(){
// ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int T=1;
// cin >> T;
while(T--) solve();
return 0;
}