Pagini recente » Cod sursa (job #619365) | Cod sursa (job #2460594) | Cod sursa (job #3196282) | Cod sursa (job #1100641) | Cod sursa (job #3138094)
#include <fstream>
#include <cstring>
using namespace std;
ifstream cin ("adn.in");
ofstream cout ("adn.out");
int dp[(1 << 18)][20];
int pre[(1 << 18)][20];
char s[20][30005];
int l[20];
int pi[20][30005];
void dani(int ind)
{
int now = 0, i;
for (i = 2; i <= l[ind]; i++)
{
now = pi[ind][i - 1];
while (now && s[ind][i] != s[ind][now + 1])
now = pi[ind][now];
if (s[ind][i] == s[ind][1 + now])
now++;
pi[ind][i] = now;
}
}
int kmp(int x, int y)
{
int now = 0, i;
for (i = 1; i <= l[x]; i++)
{
while (now && s[x][i] != s[y][now + 1])
now = pi[y][now];
if (s[x][i] == s[y][1 + now])
now++;
if (now == l[y])
return l[y];
}
return now;
}
int in[20];
int c[20][20];
void atrb(int i, int j)
{
if (kmp(i, j) == l[j])
in[j] = 1;
else
c[i][j] = -kmp(i, j);
}
void recon(int mask, int p)
{
if (mask == (1 << p))
{
cout << s[p] + 1;
return;
}
recon(mask ^ (1 << p), pre[mask][p]);
cout << (s[p] + 1 - c[pre[mask][p]][p]);
}
int main()
{
int n, final = 0, i, j, ans = 2e9, last;
cin >> n;
for (i = 0; i < n; i++)
for (j = 0; j < (1 << n); j++)
dp[j][i] = 2e9;
for (i = 0; i < n; i++)
{
cin >> (s[i] + 1);
l[i] = strlen(s[i] + 1);
dani(i); ///bebe dani
}
for (i = 0; i < n; i++)
for (j = i + 1; j < n; j++)
{
atrb(i, j);
atrb(j, i);
}
for (i = 0; i < n; i++)
if (!in[i])
{
final += (1 << i);
dp[(1 << i)][i] = 0;
}
for (int mask = 1; mask < (1 << n); mask++)
for (i = 0; i < n; i++)
if (mask & (1 << i) && !in[i])
for (j = 0; j < n; j++)
if (i != j && !in[j] && mask & (1 << j) && dp[mask][i] > dp[mask ^ (1 << i)][j] + c[j][i])
{
dp[mask][i] = min(dp[mask][i], dp[mask ^ (1 << i)][j] + c[j][i]);
pre[mask][i] = j;
}
for (i = 0; i < n; i++)
if (dp[final][i] < ans)
{
ans = dp[final][i];
last = i;
}
recon(final, last);
return 0;
}