Pagini recente » Cod sursa (job #1548639) | Cod sursa (job #1774418) | Cod sursa (job #2307864) | Cod sursa (job #147571) | Cod sursa (job #1935875)
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
using namespace std;
ifstream fin("adn.in");
ofstream fout("adn.out");
const int MAX = 18;
const int MAXL = 50005;
const int Inf = 0x3f3f3f3f;
int N;
vector<string> s;
int D[1<<MAX][MAX];
int b[MAX][MAX];
int p[MAX][MAXL];
void Read();
void Solve();
void BuildPrefix( int x );
void KMP( int x, int y );
void Write( int conf, int ul, int up );
int main()
{
Read();
Solve();
fin.close();
fout.close();
return 0;
}
void Read()
{
fin >> N; fin.get();
s = vector<string>(N);
for ( int i = 0; i < N; ++i )
{
fin >> s[i];
BuildPrefix(i);
}
/* for ( int i = 0; i < N; ++i )
fout << s[i] << '\n'; */
}
void Solve()
{
int i, j, k;
for ( i = 0; i < N; ++i )
for ( j = 0; j < N; ++j )
if ( i != j )
{
KMP(i, j);
}
int res{Inf}, u;
for ( i = 0; i < N; ++i )
D[1 << i][i] = s[i].size();
for ( i = 0; i < ( 1 << N ); ++i )
{
int c{0};
for ( j = 0; j < N; ++j )
if ( i & ( 1 << j ) )
++c;
if ( c < 2 )
continue;
for ( j = 0; j < N; ++j )
if ( i & ( 1 << j ) )
{
D[i][j] = Inf;
for ( k = 0; k < N; ++k )
if ( k != j && i & ( 1 << k ) )
{
D[i][j] = min( D[i][j], D[i ^ ( 1 << j )][k] + (int)s[j].size() - b[k][j] );
}
// fout << i << ' ' << j << ' ' << D[i][j] << '\n';
if ( i + 1 == ( 1 << N ) && D[i][j] < res )
res = D[i][j], u = j;
}
}
Write((1 << N) - 1, u, 0);
}
void Write( int conf, int ul, int up )
{
for ( int i = 0; i < N; ++i )
if ( i != ul && ( ( 1 << i ) & conf ) && D[conf][ul] == D[conf ^ ( 1 << ul )][i] + (int)s[ul].size() - b[i][ul] )
{
Write(conf ^ ( 1 << ul ), i, b[i][ul]);
break;
}
for ( int i = 0; i < s[ul].size() - up; ++i )
fout << s[ul][i];
}
void BuildPrefix( int x )
{
int k{0};
for ( int i = 1; i < s[x].size(); ++i )
{
while ( k > 0 && s[x][i] != s[x][k] )
k = p[x][k - 1];
if ( s[x][i] == s[x][k] )
++k;
p[x][i] = k;
}
}
void KMP( int x, int y )
{
int k{0};
for ( int i = 0; i < s[x].size(); ++i )
{
while ( k > 0 && s[x][i] != s[y][k] )
k = p[y][k - 1];
if ( s[x][i] == s[y][k] )
++k;
if ( k == s[y].size() - 1 )
{
b[x][y] = s[y].size();
return;
}
}
b[x][y] = k;
// fout << x << ' ' << y << ' ' << k << '\n';
}