Pagini recente » Cod sursa (job #1037113) | Cod sursa (job #660362) | Cod sursa (job #2495017) | Cod sursa (job #2712415) | Cod sursa (job #2419303)
#include <fstream>
#include <cstring>
#include <string>
using namespace std;
ifstream fin("adn.in");
ofstream fout("adn.out");
const int NMAX = 18;
const int CONFIGMAX = (1 << 18);
const int LMAX = 30001;
const int INF = 18 * 30001 + 100000;
int N;
int lg[NMAX + 5];
char str[NMAX + 5][LMAX + 5];
int cost[NMAX + 5][NMAX + 5];
bool useless[NMAX + 5];
int k;
int v[NMAX + 5];
int cost2[NMAX + 5][NMAX + 5];
int dp[CONFIGMAX + 5][NMAX + 5];
int pre[CONFIGMAX + 5][NMAX + 5];
string solll;
void Read()
{
fin >> N;
for(int i = 0; i < N; i++)
{
fin >> (str[i] + 1);
lg[i] = strlen(str[i] + 1);
}
}
int pi[LMAX + 5];
void InitPi(int ind)
{
memset(pi, 0, sizeof(pi));
int j = 0;
for(int i = 2; i <= lg[ind]; i++)
{
while(j && str[ind][j + 1] != str[ind][i])
j = pi[j];
if(str[ind][j + 1] == str[ind][i])
j++;
pi[i] = j;
}
}
void KMP(int p, int q)
{
int j = 0;
for(int i = 1; i <= lg[q]; i++)
{
while(j && str[p][j + 1] != str[q][i])
j = pi[j];
if(str[p][j + 1] == str[q][i])
j++;
if(j == lg[p])
{
useless[p] = 1;
return ;
}
}
cost[q][p] = lg[p] - j;
}
void GetCosts()
{
for(int i = 0; i < N; i++)
{
InitPi(i);
for(int j = 0; j < N; j++)
if(i != j)
KMP(i, j);
}
for(int i = 0; i < N; i++)
if(useless[i] == 0)
v[++k] = i;
for(int i = 0; i < k; i++)
for(int j = 0; j < k; j++)
if(i != j)
cost2[i][j] = cost[v[i]][v[j]];
}
int ksol;
int sol[NMAX + 5];
void Solve()
{
for(int i = 0; i < (1 << k); i++)
for(int j = 0; j < k; j++)
dp[i][j] = INF;
for(int i = 0; i < k; i++)
dp[1 << i][i] = lg[v[i]];
for(int config = 1; config < (1 << k); config++)
for(int f = 0; f < N; f++)
if(config & (1 << f))
for(int j = 0; j < N; j++)
if(f != j && (config & (1 << j)))
if(dp[config ^ (1 << f)][j] + cost2[j][f] < dp[config][f])
{
dp[config][f] = dp[config ^ (1 << f)][j] + cost2[j][f];
pre[config][f] = j;
}
int ans = INF, lastPos;
for(int i = 0; i < k; i++)
if(dp[(1 << k) - 1][i] < ans)
{
ans = dp[(1 << k) - 1][i];
lastPos = i;
}
int mask = (1 << k) - 1;
while(mask)
{
sol[++ksol] = lastPos;
int prevPos = pre[mask][lastPos];
mask = mask ^ (1 << lastPos);
lastPos = prevPos;
}
int skip = 0;
for(int i = ksol; i >= 1; i--)
{
for(int j = skip + 1; j <= lg[v[sol[i]]]; j++)
solll += str[v[sol[i]]][j];
skip = lg[v[sol[i - 1]]] - cost2[v[sol[i]]][v[sol[i - 1]]];
}
fout << solll;
}
int main()
{
Read();
GetCosts();
Solve();
return 0;
}