Pagini recente » Cod sursa (job #1153471) | Cod sursa (job #2869372) | Cod sursa (job #903970) | Cod sursa (job #820837) | Cod sursa (job #311236)
Cod sursa(job #311236)
#include <fstream>
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
#define MAXN 18
#define MAXL 30010
#define MASK (1<<MAXN)
ifstream in("adn.in");
ofstream out("adn.out");
char C[MAXN][MAXL];
int L[MAXN], N, i, M;
int G[MAXN][MAXN], tmp[MAXN];
int pi[MAXL];
bool Disabled[MAXN];
bool Used[MASK];
int A[MAXN][MASK];
char Last[MAXN][MASK];
queue<int> Q;
void back_print(int n, int mask) {
cerr << n << " " << mask << "\n";
if ( (mask&(-mask)) == mask ) {
for (int i=1; i<=L[n]; ++i)
out << C[n][i];
return;
}
int l = Last[n][mask];
back_print(l, mask-(1<<n));
for (int i=G[l][n]+1; i<=L[n]; ++i)
out << C[n][i];
}
int main() {
in >> N;
char c_tmp;
in.get(c_tmp);
for (i=0; i<N; ++i) {
in.getline(C[i]+1, MAXL-1);
for (L[i]=strlen(C[i]+1); C[i][L[i]]>'T' || C[i][L[i]]<'A'; --L[i])
C[i][L[i]] = 0;
}
// preprocesare suprapuneri O(N^2*L)
for (i=0; i<N; ++i) {
int k=0, j, t;
pi[1] = 0;
for (j=2; j<=L[i]; ++j) {
while (C[i][j]!=C[i][k+1] && k) k=pi[k];
if (C[i][j]==C[i][k+1]) ++k;
pi[j] = k;
}
for (t=0; t<N && !Disabled[i]; ++t) {
if ( i==t ) continue;
for (k=0, j=1; j<=L[t]; ++j) {
while (C[i][k+1]!=C[t][j] && k) k=pi[k];
if (C[i][k+1]==C[t][j]) ++k;
if (k==L[i]) {
Disabled[i] = true;
break;
}
}
tmp[t] = k;
}
if ( !Disabled[i] )
for (j=0; j<N; ++j)
G[j][i] = tmp[j];
}
// dinamica O(N^2*2^N) in
/*
A[i][mask] = lungimea minima a secventei care se termina
in C[i] si are folosite elementele din repr binara a mastii
*/
memset(A, 0x3f, sizeof(A));
M = (1<<N) - 1;
for (i=0; i<N; ++i) {
if ( Disabled[i] ) {
M -= 1<<i;
continue;
}
A[i][1<<i] = L[i];
Q.push(1<<i); Used[1<<i] = true;
}
while ( !Q.empty() ) {
int x = Q.front(); Q.pop(); Used[x] = false;
for (i=0; i<N; ++i) {
if ( (x&(1<<i))==0 ) continue;
for (int j=0; j<N; ++j) {
if ( Disabled[j] || (x&(1<<j)) ) continue;
int y = x + (1<<j);
if ( !Used[y] ) { Q.push(y); Used[y] = true; }
if ( A[j][y] > A[i][x] + L[j] - G[i][j] )
A[j][y] = A[i][x] + L[j] - G[i][j], Last[j][y] = i;
}
}
}
int m = 0;
for (i=1; i<N; ++i)
if ( A[i][M] < A[m][M] )
m = i;
back_print(m, M);
out << "\n";
return 0;
}