Pagini recente » Cod sursa (job #312328) | Cod sursa (job #1394600) | Cod sursa (job #1841291) | Cod sursa (job #792378) | Cod sursa (job #1726756)
#include <algorithm>
#include <fstream>
#include <vector>
#include <cstring>
using namespace std;
ifstream f("adn.in");
ofstream g("adn.out");
const int NM = 30005;
int Ans, ans, i, N, n, m, interzis=0, pi[NM], sz[20], j, x[20][20], mask, A, B;
int dp[(1<<18)+1][20], r[(1<<18)+1][20];
char a[20][NM], ch[20*NM];
bool Ok;
vector<int> v1, v2;
void Kmp(char a[], int n)
{
int i, k=0;
pi[1]=0;
for(i=2; i<=n; ++i)
{
while(k && a[k+1]!=a[i])
k=pi[k];
if(a[k+1]==a[i]) ++k;
pi[i]=k;
}
}
int kmp(char a[], char b[], int n, int m)
{
int i, k=0;
for(i=1; i<=m; ++i)
{
while(k && a[k+1]!=b[i])
k=pi[k];
if(a[k+1]==b[i]) ++k;
if(k==n) Ok=0;
}
return k;
}
int main()
{
f>>n;
for(i=0; i<n; ++i)
{
f>>(a[i]+1);
sz[i] = strlen(a[i]+1);
}
for(i=0; i<n; ++i)
{
Ok=1;
Kmp(a[i], sz[i]);
for(j=0; j<n; ++j)
if(i!=j)
x[j][i] = kmp(a[i], a[j], sz[i], sz[j]); /// a[i] - prefix
/// a[j] - sufix
if(!Ok) interzis += (1<<i);
else Ans += sz[i];
r[1<<i][i] = n;
}
for(mask=1; mask<(1<<n); ++mask)
if(!(mask&interzis))
{
v1.clear();
v2.clear();
for(i=0; i<n; ++i)
if(!((1<<i)&interzis))
{
if(mask&(1<<i)) v1.push_back(i);
else v2.push_back(i);
}
for(i=0; i<v1.size(); ++i)
for(j=0; j<v2.size(); ++j)
{
A = v1[i];
B = v2[j];
if( dp[mask^(1<<B)][B] < dp[mask][A] + x[A][B] )
{
dp[mask^(1<<B)][B] = dp[mask][A] + x[A][B];
r[mask^(1<<B)][B] = A;
}
}
}
mask = (mask-1)^interzis;
for(i=0; i<n; ++i)
if( !(interzis&(1<<i)) && ans<dp[mask][i])
{
ans = dp[mask][i];
A = i;
}
int ind = Ans - ans;
while(mask)
{
for(i=sz[A]; i > x[ r[mask][A] ][A]; --i)
ch[ind--] = a[A][i];
mask -= (1<<A);
A = r[mask+(1<<A)][A];
}
g<<(ch+1)<<'\n';
return 0;
}