Pagini recente » Cod sursa (job #2307442) | Cod sursa (job #335649) | Cod sursa (job #1286728) | Cod sursa (job #206436) | Cod sursa (job #1200855)
#include <iostream>
#include <fstream>
#include <cstring>
#include <algorithm>
using namespace std;
const int Nmax = 18;
const int Lmax = 1e5 + 2;
const int inf = 0x3f3f3f3f;
char S[Nmax][Lmax];
int C[Nmax][Nmax];
int D[1 << Nmax][Nmax];
int pi[Lmax];
int lg[Nmax];
int N;
void build_prefix( char s[] )
{
int lgprefix = 0;
int n = strlen( s + 1 );
pi[1] = 0;
for ( int i = 2; i <= n; ++i )
{
while ( lgprefix && s[i] != s[lgprefix + 1] )
lgprefix = pi[lgprefix];
if ( s[i] == s[lgprefix + 1] )
lgprefix++;
pi[i] = lgprefix;
}
}
int KMP_cost( char patt[], char text[] )
{
int n = strlen( patt + 1 );
int m = strlen( text + 1 );
int lgprefix = 0;
for ( int i = 1; i <= m; ++i )
{
while ( lgprefix && text[i] != patt[lgprefix + 1] )
lgprefix = pi[lgprefix];
if ( text[i] == patt[lgprefix + 1] )
lgprefix++;
if ( lgprefix == n )
return n;
}
return lgprefix;
}
int cycle( int stare, int nodAnterior )
{
if ( D[stare][nodAnterior] != -1 )
return D[stare][nodAnterior];
if ( stare == ( 1 << N ) - 1 )
{
return 0;
}
else
{
D[stare][nodAnterior] = -inf;
for ( int i = 0; i < N; ++i )
{
if ( ( stare & ( 1 << i ) ) == 0 )
{
int ans = C[nodAnterior][i] + cycle( stare ^ ( 1 << i ), i );
if ( ans > D[stare][nodAnterior] )
{
D[stare][nodAnterior] = ans;
}
}
}
return D[stare][nodAnterior];
}
}
int sol[Nmax];
int P[Nmax];
void perm()
{
for ( int i = 0; i < N; ++i )
P[i] = i;
int maxim = 0;
do
{
int sum = 0;
for ( int i = 0; i < N - 1; ++i )
sum += C[ P[i] ][ P[i + 1] ];
if ( sum > maxim )
{
for ( int i = 0; i < N; ++i )
sol[i] = P[i];
maxim = sum;
}
} while ( next_permutation( P, P + N ) );
int sum = 0;
for ( int i = 0; i < N; ++i )
sum += strlen( S[i] + 1 );
ofstream cout("adn.out");
cout << sum - maxim << endl;
}
int main()
{
ifstream cin("adn.in");
cin >> N;
for ( int i = 0; i < N; ++i )
{
cin >> ( S[i] + 1 );
lg[i] = strlen( S[i] + 1 );
}
for ( int i = 0; i < N; ++i )
{
build_prefix( S[i] );
for ( int j = 0; j < N; ++j )
{
int kmp = KMP_cost( S[i], S[j] );
if ( kmp == lg[i] )
{
for ( int k = i; k < N - 1; ++k )
{
strcpy( S[k] + 1, S[k + 1] + 1 );
}
i -= 2;
N--;
if ( i < -1 ) i = -1;
break;
}
}
}
for ( int i = 0; i < N; ++i )
{
build_prefix( S[i] );
for ( int j = 0; j < N; ++j )
if ( i != j )
C[j][i] = KMP_cost( S[i], S[j] );
}
// for ( int i = 0; i < ( 1 << N ); ++i )
// for ( int j = 0; j < N; ++j )
// D[i][j] = -1;
// for ( int i = 0; i < N; ++i, cout << endl )
// for ( int j = 0; j < N; ++j )
// cout << C[i][j] << " ";
/**for ( int i = 0; i < N; ++i )
{
cout << cycle( 1 << i, i ) << "\n";
}
cout << endl;
**/
perm();
/** for ( int i = 0; i < N - 1; ++i )
{
int cat = strlen( S[ sol[i] ] + 1 ) - C[ sol[i] ][ sol[i + 1] ];
for ( int j = 1; j <= cat; ++j )
cout << S[ sol[i] ][j];
}
for ( int j = 1; j <= strlen( S[ sol[N - 1] ] + 1 ); ++j )
cout << S[ sol[N - 1] ][j];
**/
return 0;
}