Pagini recente » Cod sursa (job #2432466) | Cod sursa (job #1224966) | Cod sursa (job #1648145) | Cod sursa (job #874300) | Cod sursa (job #2467751)
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
const int NMAX = 22;
const int LMAX = 30005;
ifstream cin ("adn.in");
ofstream cout ("adn.out");
int cut[NMAX];
int len[NMAX][NMAX];
int dp[(1 << 18)][NMAX];
int k[LMAX * 2];
int recon[(1 << 18)][NMAX];
int kmp(string a, string b)
{
string s;
s="?" + a;
s=s + "#";
s=s + b;
for(int i=0; i < (int)s.size(); ++ i)
k[i] = 0;
for(int i = 2; i < (int)s.size(); ++ i) {
int q = k[i-1];
while(q && s[i] != s[q+1])
q = k[q];
if(s[q+1] == s[i])
++ q;
k[i] = q;
}
return k[s.size() - 1];
}
int main()
{
vector <string> initial;
vector <string> v;
int n;
cin>>n;
for(int i = 1; i <= n; ++ i) {
string s;
cin>>s;
initial.push_back(s);
}
for(int i = 0; i < (int)initial.size(); ++ i) {
for(int j = 0; j < (int)initial.size(); ++ j) {
if(i != j && (int)initial[j].size() >= (int)initial[i].size() && cut[j] == 0) {
for(int st = 0; st <= (int)initial[j].size() - (int)initial[i].size(); ++ st) {
bool ok = 1;
for(int k = st; k <= st + (int)initial[i].size() - 1; ++k) {
if(initial[j][k] != initial[i][k - st]) {
ok = 0;
break;
}
}
if(ok == 1) {
cut[i] = 1;
break;
}
}
}
}
if(cut[i] == 0)
v.push_back(initial[i]);
}
n = v.size();
for(int i = 0; i < n; ++ i)
for(int j = 0; j < n; ++ j)
if(i != j)
len[i][j] = kmp(v[i], v[j]);
for(int i = 0; i < n; ++ i) {
dp[1 << i][i] = (int)v[i].size();
recon[1 << i][i] = -1;
}
for(int masca = 1; masca <= (1 << n) - 1; ++ masca)
for(int bit = 0; bit < n; ++ bit)
if(masca & (1 << bit))
for (int new_bit = 0 ; new_bit < n; ++ new_bit)
if(!(masca & (1 << new_bit))) {
if(dp[masca | (1 << new_bit)][new_bit] == 0 || (dp[masca | (1 << new_bit)][new_bit] > dp[masca][bit] + (int)v[new_bit].size() - len[bit][new_bit])) {
dp[masca | (1 << new_bit)][new_bit] = dp[masca][bit] + (int)v[new_bit].size() - len[bit][new_bit];
recon[masca | (1 << new_bit)][new_bit] = bit;
}
}
int ans = dp[(1 << n) - 1][0];
int last = 0;
for(int j = 1; j < n; ++ j) {
if(dp[(1 << n) - 1][j] < ans) {
ans = dp[(1 << n) - 1][j];
last = j;
}
}
int masca = (1 << n) - 1;
int prec = 0;
while(prec != -1) {
int prec = recon[masca][last];
if(prec == -1) {
cout<<v[last]<<"\n";
return 0;
}
for(int i = 0; i < (int)v[last].size() - len[prec][last]; ++ i)
cout<<v[last][i];
masca = masca - (1 << last);
last = prec;
}
return 0;
}