Pagini recente » Cod sursa (job #208789) | Cod sursa (job #1312816) | Cod sursa (job #571410) | Cod sursa (job #2840393) | Cod sursa (job #2027389)
#include <bits/stdc++.h>
#define NMAX 30005
#define MOD 666013
#define INF 0x3f3f3f3f
#define x first
#define y second
#define pb push_back
using namespace std;
ifstream fin("adn.in");
ofstream fout("adn.out");
char s[20][NMAX],final[20*NMAX];
int pref[20][NMAX],dist[20][20],dp[1<<19][20],Prev[1<<19][20],lg[20];
void prefix(int care) {
int i,p,n;
p=0;
n=lg[care];
for(i=2;i<=n;++i) {
while(p && s[care][p+1]!=s[care][i])
p=pref[care][p];
if(s[care][p+1] == s[care][i]) ++p;
pref[care][i]=p;
}
}
int calcDist(int a, int b) {
int i,p,lg1=lg[a],lg2=lg[b];
p=0;
for(i=1;i<=lg1;++i) {
while(p && s[b][p+1]!=s[a][i])
p=pref[b][p];
if(s[b][p+1] == s[a][i]) ++p;
if(p==lg2) return -1;
}
return p;
}
int main() {
int n,i,j,k=0,usable,x;
fin>>n;
usable=(1<<n)-1;
for(i=1;i<=n;++i) {
fin>>(s[i]+1);
lg[i]=strlen(s[i]+1);
}
for(i=1;i<=n;++i) {
for(j=1;j<=n;++j) {
if(i==j) continue;
x=calcDist(i,j);
dist[i][j]=lg[j]-x;
if(x==-1)
usable=(usable&((1<<n)-1))-(1<<(j-1));
}
}
for(i=0;i<=n;i++) {
dist[i][0]=dp[0][i]=INF;
dist[0][i]=lg[i];
}
dp[0][0]=0;
for(i=1;i<=usable;i++) {
dp[i][0]=INF;
for(j=1;j<=n;j++) {
dp[i][j]=INF;
if(i&(1<<(j-1))) {
for(k=0;k<=n;k++) {
if(k==0 || ((i&(1<<(k-1))) && k!=j && dp[i][j]>dp[i^(1<<(j-1))][k]+dist[k][j])) {
dp[i][j]=dp[i^(1<<(j-1))][k]+dist[k][j];
Prev[i][j]=k;
}
}
}
}
}
int nod=1,pre=0,ind=0;
for(int i=1;i<=n;i++)
if(dp[usable][i]<dp[usable][nod])
nod=i;
stack<int> st;
while(usable) {
st.push(nod);
usable^=(1<<(nod-1));
nod=Prev[usable^(1<<(nod-1))][nod];
}
while(!st.empty()) {
for(int i=lg[st.top()]-dist[pre][st.top()]+1;i<=lg[st.top()];i++)
final[ind++]=s[st.top()][i];
pre=st.top();
st.pop();
}
fout<<final;
return 0;
}