Pagini recente » Cod sursa (job #2062008) | Cod sursa (job #2805101) | Cod sursa (job #2062595) | Cod sursa (job #2271701) | Cod sursa (job #2962723)
#include <fstream>
#include <vector>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
ifstream in("adn.in");
ofstream out("adn.out");
const int NMAX = 19, MMAX = 30005, INF = 2e9;
char s[NMAX][MMAX];
int N, dp[(1 << NMAX)][NMAX], Lengths[NMAX], p[MMAX], Father[(1 << NMAX)][NMAX], Cost[NMAX][NMAX], f[NMAX];
vector<pair<int, int>> Edges[NMAX];
vector<int> v;
int main()
{
in >> N;
for (int i = 1; i <= N; i++)
{
in >> s[i] + 1;
Lengths[i] = strlen(s[i] + 1);
}
for (int i = 1; i <= N; i++)
{
memset(p, 0, sizeof(p));
int l = 0;
for (int j = 2; j <= Lengths[i]; j++)
{
while (l && s[i][j] != s[i][l + 1])
l = p[l];
if (s[i][j] == s[i][l + 1])
l++;
p[j] = l;
}
for (int j = 1; j <= N; j++)
{
if (i == j)
continue;
int l = 0, ok = 0;
for (int k = 1; k <= Lengths[j]; k++)
{
while (l && s[j][k] != s[i][l + 1])
l = p[l];
if (s[j][k] == s[i][l + 1])
l++;
if (l == Lengths[i])
{
ok = 1;
break;
}
}
if (ok)
{
Edges[i - 1].push_back({j - 1, 0});
f[i] = 1;
Cost[j - 1][i - 1] = 0;
}
else
{
Edges[i - 1].push_back({j - 1, Lengths[i] - l});
Cost[j - 1][i - 1] = Lengths[i] - l;
}
}
}
int M = (1 << N);
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
dp[i][j] = INF;
int FinalMask = 0;
for (int i = 0; i < N; i++)
if (!f[i + 1])
{
dp[(1 << i)][i] = Lengths[i + 1];
FinalMask += (1 << i);
}
for (int state = 1; state <= FinalMask; state++)
{
for (int i = 0; i < N; i++)
{
if (!(state & (1 << i)) || f[i + 1])
continue;
for (auto it : Edges[i])
{
int vecin = it.first, cost = it.second;
if (!(state & (1 << vecin)) || f[vecin + 1])
continue;
if (dp[state - (1 << i)][vecin] + cost < dp[state][i])
{
dp[state][i] = dp[state - (1 << i)][vecin] + cost;
Father[state][i] = vecin;
}
}
}
}
int sol = INF, last = 0;
for (int i = 0; i < N; i++)
if (!f[i + 1] && dp[FinalMask][i] < sol)
{
sol = dp[FinalMask][i];
last = i;
}
int x = FinalMask, y = last;
v.push_back(y);
while (x)
{
int aux = (1 << y);
y = Father[x][y];
x -= aux;
v.push_back(y);
}
v.pop_back();
reverse(v.begin(), v.end());
out << s[v[0] + 1] + 1;
for (int i = 1; i < v.size(); i++)
{
int idx = v[i] + 1, val = Cost[v[i - 1]][v[i]];
for (int j = Lengths[idx] - val + 1; j <= Lengths[idx]; j++)
out << s[idx][j];
}
return 0;
}