Pagini recente » Cod sursa (job #1711635) | Cod sursa (job #536702) | Cod sursa (job #2586190) | Cod sursa (job #1879922) | Cod sursa (job #825341)
Cod sursa(job #825341)
#include <fstream>
#include <cstring>
#include <cstdio>
#define MAX 19
#define LMAX 30005
#define INF 0x3f3f3f3f
using namespace std;
int N;
int cost[MAX][MAX], P[LMAX], L[MAX], dp[(1 << MAX)][MAX], dad[(1 << MAX)][MAX];
char sir[MAX][LMAX];
void buildPrefix(int n)
{
memset(P, 0, sizeof(P));
int k = 0;
for(int i = 2; i <= L[n]; i++)
{
while(k && sir[n][k + 1] != sir[n][i]) k = P[k];
if(sir[n][k + 1] == sir[n][i]) k++;
P[i] = k;
}
}
int KMP(int n, int m)
{
int k = 0;
for(int i = 1; i <= L[m]; i++)
{
while(k && sir[n][k + 1] != sir[m][i]) k = P[k];
if(sir[n][k + 1] == sir[m][i]) k++;
if(k == L[n]) return -1;
}
return k;
}
void preprocess()
{
for(int i = 0; i < N; i++)
L[i] = strlen(sir[i] + 1);
for(int i = 0; i < N; i++)
{
buildPrefix(i);
for(int j = 0; j < N; j++)
if(i != j && KMP(i, j) == -1)
{
memcpy(sir[i], sir[N - 1], LMAX);
L[i] = L[N - 1];
N--; i--;
break;
}
}
for(int i = 0; i < N; i++)
{
buildPrefix(i);
for(int j = 0; j < N; j++)
if(i != j) cost[j][i] = L[i] - KMP(i, j);
}
}
void init()
{
for(int i = 0; i < (1 << N); i++)
for(int j = 0; j < N; j++)
dp[i][j] = INF;
for(int i = 0; i < N; i++)
dp[(1 << i)][i] = L[i], dad[(1 << i)][i] = -1;
}
void afisare(int conf, int last)
{
if(dad[conf][last] == -1) { printf("%s", sir[last] + 1); return; }
afisare(conf ^ (1 << last), dad[conf][last]);
printf("%s", sir[last] + (L[last] - cost[dad[conf][last]][last] + 1));
}
int main()
{
ifstream in("adn.in");
in>>N; in.get();
for(int i = 0; i < N; i++) in.getline(sir[i] + 1, LMAX);
in.close();
preprocess();
init();
for(int conf = 1; conf < (1 << N); conf++)
{
for(int i = 0; i < N; i++)
{
if(!(conf & (1 << i))) continue;
for(int j = 0; j < N; j++)
{
if(!(conf & (1 << j)) || i == j) continue;
if(dp[conf][i] > dp[conf ^ (1 << i)][j] + cost[j][i])
dp[conf][i] = dp[conf ^ (1 << i)][j] + cost[j][i], dad[conf][i] = j;
}
}
}
int best = INF, indInf;
for(int i = 0; i < N; i++)
if(dp[(1 << N) - 1][i] < best) best = dp[(1 << N) - 1][i], indInf = i;
freopen("adn.out", "w", stdout);
afisare((1 << N) - 1, indInf);
fclose(stdout);
return 0;
}