Pagini recente » Cod sursa (job #2003355) | Cod sursa (job #937994) | Cod sursa (job #2124506) | Cod sursa (job #1725760) | Cod sursa (job #2433409)
#include <bits/stdc++.h>
using namespace std;
ifstream in("adn.in");
ofstream out("adn.out");
const int INF = 1e8;
string s[20];
int prefix[20][30017];
int dp[(1 << 19)][20];
pair <int, int> from[(1 << 19)][20];
int c[20][20];
void build(int pos)
{
int n = s[pos].size();
s[pos] = ' ' + s[pos];
int k = 0;
for(int i = 2; i <= n; i++)
{
while(k != 0 && s[pos][k + 1] != s[pos][i])
k = prefix[pos][k];
if(s[pos][k + 1] == s[pos][i])
k++;
prefix[pos][i] = k;
}
}
void get(int x, int y)
{
if(c[y][x] == 0)
return ;
int m1 = s[x].size() - 1;
int m2 = s[y].size() - 1;
int k = 0;
for(int i = 1; i <= m2; i++)
{
while(k != 0 && s[x][k + 1] != s[y][i])
k = prefix[x][k];
if(s[x][k + 1] == s[y][i])
k++;
if(k == m1)
{
c[y][x] = 0;
return ;
}
if(i == m2)
{
c[y][x] = m1 - k;
return ;
}
}
}
int last = -1;
void afiseaza(int mask, int p)
{
if(from[mask][p] != make_pair(0, 0))
afiseaza(from[mask][p].first, from[mask][p].second);
if(last == -1)
{
out << s[p];
}
else
{
int m = s[p].size() - 1;
for(int j = m - c[last][p] + 1; j <= m; j++)
out << s[p][j];
}
last = p;
}
main()
{
int n;
in >> n;
for(int i = 0; i < n; i++)
{
in >> s[i];
build(i);
}
for(int j = 0; j < n; j++)
{
for(int i = 0; i < n; i++)
c[i][j] = INF;
for(int i = 0; i < (1 << n); i++)
dp[i][j] = INF;
}
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
if(i != j)
get(i, j);
for(int i = 0; i < n; i++)
dp[(1 << i)][i] = s[i].size() - 1;
for(int i = 0; i < (1 << n); i++)
for(int j = 0; j < n; j++)
if(i & (1 << j))
for(int k = 0; k < n; k++)
if(i & (1 << k))
if(dp[i][j] > dp[i ^ (1 << j)][k] + c[k][j])
{
dp[i][j] = dp[i ^ (1 << j)][k] + c[k][j];
from[i][j] = {i ^ (1 << j), k};
}
int start = 0;
for(int i = 0; i < n; i++)
if(dp[(1 << n) - 1][i] < dp[(1 << n) - 1][start])
start = i;
afiseaza((1 << n) - 1, start);
}