wa20求助,玄关
查看原帖
wa20求助,玄关
1251532
apiad楼主2024/3/8 23:44

本代码在 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;
}
2024/3/8 23:44
加载中...