Pagini recente » Cod sursa (job #2303238) | Cod sursa (job #629331) | Cod sursa (job #2523192) | Cod sursa (job #2599045) | Cod sursa (job #2801036)
#include <bits/stdc++.h>
using namespace std;
inline void Open(const string Name) {
#ifndef ONLINE_JUDGE
(void)!freopen((Name + ".in").c_str(), "r", stdin);
(void)!freopen((Name + ".out").c_str(), "w", stdout);
#endif
}
const int INF = 1e9;
bitset <19> marked;
vector <array <int, 2>> Gr[19];
array <int, 2> path[1 << 19][19];
int dp[1 << 19][19], cost[19][19];
int pi[60005];
string v[19];
void printSTR(array <int, 2> cur) {
if(cur[0] == 0)
return;
printSTR(path[cur[0]][cur[1]]);
int wcost = cost[path[cur[0]][cur[1]][1]][cur[1]];
if(path[cur[0]][cur[1]][0] == 0)
wcost = 0;
cout << v[cur[1]].substr(wcost);
}
bool KMP(string str1, string str2) {
str1 = ' ' + str1;
str2 = ' ' + str2;
int len = str1.size() - 1, lenn = str2.size() - 1, q = 0;
pi[1] = 0;
for(int i = 2;i <= len;i++) {
while(q && str1[q + 1] != str1[i])
q = pi[q];
if(str1[q + 1] == str1[i])
q++;
pi[i] = q;
}
q = 0;
for(int i = 1;i <= lenn;i++) {
while(q && str1[q + 1] != str2[i])
q = pi[q];
if(str1[q + 1] == str2[i])
q++;
if(q == len)
return 1;
}
return 0;
}
int LenPS(string str1, string str2) {
string str = "2" + str2 + "2" + str1;
int len = str.size(), q = 0;
pi[1] = 0;
for(int i = 2;i < len;i++) {
while(q && str[q + 1] != str[i])
q = pi[q];
if(str[q + 1] == str[i])
q++;
pi[i] = q;
}
return pi[len - 1];
}
bool cmp(string str1, string str2) {
return str1.size() < str2.size();
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
Open("adn");
int N; cin >> N;
for(int i = 0;i < N;i++)
cin >> v[i];
sort(v, v + N, cmp);
for(int i = 0;i < N - 1;i++)
for(int j = i + 1;j < N;j++)
if(KMP(v[i], v[j]) == 1) {
marked[i] = 1;
break;
}
int cnt = 0;
for(int i = 0;i < N;i++) {
if(!marked[i]) {
v[cnt++] = v[i];
}
}
N = cnt;
for(int i = 0;i < N;i++)
for(int j = 0;j < N;j++)
if(i != j) {
int val = LenPS(v[i], v[j]);
Gr[j].push_back({i, val});
cost[i][j] = val;
}
int limit = 1 << N;
for(int i = 0;i < limit;i++)
for(int j = 0;j < N;j++)
dp[i][j] = -INF;
for(int i = 0;i < N;i++)
dp[1 << i][i] = 0;
for(int i = 0;i < limit;i++)
for(int j = 0;j < N;j++) {
if((i & (1 << j)) == 0)
continue;
for(array <int, 2> it : Gr[j]) {
if((i & (1 << it[0])) == 0)
continue;
if(dp[i ^ (1 << j)][it[0]] + it[1] > dp[i][j]) {
dp[i][j] = dp[i ^ (1 << j)][it[0]] + it[1];
path[i][j] = {i ^ (1 << j), it[0]};
}
}
}
int ans = -INF;
array <int, 2> ppp;
for(int i = 0;i < N;i++){
if(dp[limit - 1][i] > ans) {
ans = dp[limit - 1][i];
ppp = {limit - 1, i};
}
}
printSTR(ppp);
return 0;
}