Pagini recente » Cod sursa (job #2010760) | Cod sursa (job #84867) | Cod sursa (job #2572784) | Cod sursa (job #1695170) | Cod sursa (job #2432768)
#include <bits/stdc++.h>
using namespace std;
ifstream in("adn.in");
ofstream out("adn.out");
const int DIM = 18;
const int INF = 1e9;
int dp[(1 << DIM) + 7][DIM + 7];
pair <int, int> from[(1 << DIM) + 7][DIM + 7];
int c[DIM][DIM];
int prefix[DIM + 7][DIM + 7];
string s[DIM + 7];
vector <int> v[DIM + 7];
bool is[DIM + 7];
void build(int p)
{
memset(prefix[p], 0, sizeof(prefix[p]));
int k = 0;
int n = s[p].size();
s[p] = ' ' + s[p];
for(int i = 2; i <= n; i++)
{
while(k != 0 && s[k + 1] != s[i])
k = prefix[p][k];
if(s[k + 1] == s[i])
k++;
prefix[p][i] = k;
}
}
bool verifica(int x, int y)
{
int k = 0;
int n = s[x].size() - 1;
int m = s[y].size() - 1;
for(int i = 1; i <= m; 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 == n)
{
is[x] = true;
return false;
}
if(i == m)
c[y][x] = n - k;
}
return true;
}
vector <int> ind;
void print(int mask, int last, int p)
{
if(p - 1)
print(from[mask][last].first, from[mask][last].second, p - 1);
int l = s[ind[last]].size() - 1;
if(p == 1)
{
for(int i = 1; i <= l; i++)
out << s[ind[last]][i];
}
else
{
for(int i = l - c[ind[from[mask][last].second]][ind[last]] + 1; i <= l; i++)
out << s[ind[last]][i];
}
}
main()
{
int n;
in >> n;
for(int i = 1; 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 = 1; i < n; i++)
for(int j = i + 1; j <= n; j++)
{
verifica(i, j);
verifica(j, i);
}
for(int i = 1; i <= n; i++)
if(is[i] == false)
ind.push_back(i);
n = ind.size();
for(int i = 0; i < n; i++)
dp[(1 << i)][i] = s[ind[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 << j))
if(dp[i][j] > dp[i ^ (1 << j)][k] + c[ind[k]][ind[j]])
{
dp[i][j] = dp[i ^ (1 << j)][k] + c[ind[k]][ind[j]];
from[i][j] = {i ^ (1 << j), k};
}
int start = 0;
for(int i = 1; i < n; i++)
if(dp[(1 << n) - 1][start] > dp[(1 << n) - 1][i])
start = i;
print((1 << n) - 1, start, n);
}