Pagini recente » Cod sursa (job #2803780) | Cod sursa (job #1194285) | Cod sursa (job #2714980) | Cod sursa (job #2715083) | Cod sursa (job #1173502)
#include <fstream>
#include <vector>
#include <string>
using namespace std;
const int N = 18, SMAX = 1 << 18, LEN = 30005;
ifstream fin ("adn.in");
ofstream fout ("adn.out");
string s[N];
bool match[N];
int a[N][N], d[N][SMAX], n, U[LEN], t[N][SMAX];
int Dyn(int x, int stare) {
if (d[x][stare] != -1)
return d[x][stare];
d[x][stare] = 0;
for (int i = 0; i < n; ++i)
if ((1 << i) & stare && d[x][stare] < Dyn(i, stare - (1 << i)) + a[i][x]) {
d[x][stare] = d[i][stare - (1 << i)] + a[i][x];
t[x][stare] = i;
}
return d[x][stare];
}
int kmp(string &a, string &b, bool type) {
if (!type && a.size() > b.size())
return 0;
int sz_a = a.size() - 1, sz_b = b.size() - 1, k = 0;
for (int i = 2; i <= sz_a; ++i) {
while (k && a[k+1] != a[i])
k = U[k];
if (a[k+1] == a[i])
k++;
U[i] = k;
}
k = 0;
for (int i = 1; i <= sz_b; ++i) {
while (k && a[k+1] != b[i])
k = U[k];
if (a[k+1] == b[i])
k++;
if (k == sz_a) {
if (!type)
return 1;
if (i != sz_b)
k = U[k];
}
}
return (type ? k : 0);
}
void write(int x, int stare) {
vector <int> wr;
while (1) {
wr.push_back (x);
if (!stare)
break;
int aux_x = x;
x = t[x][stare];
stare -= 1 << x;
}
for (int i = wr.size() - 1; i >= 0; --i)
if (i) {
for (int j = 1; j < s[wr[i]].size() - a[wr[i]][wr[i-1]]; j++)
fout << s[wr[i]][j];
}
else
for (int j = 1; j < s[wr[i]].size(); ++j)
fout << s[wr[i]][j];
}
int main() {
fin >> n;
for (int i = 0; i < n; ++i) {
string Input;
fin >> Input;
s[i] = ' ' + Input;
}
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
if (i != j && !match[i] && !match[j])
match[i] = kmp(s[i], s[j], 0);
for (int i = 0; i < n; ++i)
if (match[i]) {
n--;
for (int j = i; j < n; ++j) {
match[j] = match[j+1];
s[j] = s[j+1];
}
i--;
}
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
if (i != j)
a[i][j] = kmp(s[j], s[i], 1);
for (int i = 0; i < n; ++i) {
for (int j = 1; j < SMAX; ++j)
d[i][j] = -1;
d[i][0] = 0;
}
int best = 0;
for (int i = 0; i < n; ++i)
best = max(best, Dyn(i, (1 << n) - 1 - (1 << i)));
for (int i = 0; i < n; ++i)
if (best == d[i][(1 << n) - 1 - (1 << i)]) {
write (i, (1 << n) - 1 - (1 << i));
break;
}
}