Pagini recente » Cod sursa (job #490939) | Cod sursa (job #2893857) | Cod sursa (job #2932617) | Cod sursa (job #1726015) | Cod sursa (job #2961948)
#include<bits/stdc++.h>
#define INF 2000000000
using namespace std;
ifstream f("adn.in");
ofstream g("adn.out");
struct elem
{
int x,c;
};
vector<elem>a[20];
vector<int>v;
char s[20][30002];
int nu[20],lps[30002],cc[20][20];
int dp[262150][20];
bool kmp1(int p,int q)
{
int n1,n2,x,i;
n1=strlen(s[p]+1);
n2=strlen(s[q]+1);
for(i=0;i<=n1||i<=n2;i++)
lps[i]=0;
for(i=2;i<=n1;i++)
{
x=lps[i-1];
while(x>0&&s[p][x+1]!=s[p][i])
x=lps[x];
if(s[p][x+1]==s[p][i])
x++;
lps[i]=x;
}
x=0;
for(i=1;i<=n2;i++)
{
while(x>0&&s[p][x+1]!=s[q][i])
x=lps[x];
if(s[p][x+1]==s[q][i])
x++;
if(x==n1)
return 0;
}
return 1;
}
int kmp2(int q,int p)
{
int n1,n2,x,i;
n1=strlen(s[p]+1);
n2=strlen(s[q]+1);
for(i=0;i<=n1||i<=n2;i++)
lps[i]=0;
for(i=2;i<=n1;i++)
{
x=lps[i-1];
while(x>0&&s[p][x+1]!=s[p][i])
x=lps[x];
if(s[p][x+1]==s[p][i])
x++;
lps[i]=x;
}
x=0;
for(i=1;i<=n2;i++)
{
while(x>0&&s[p][x+1]!=s[q][i])
x=lps[x];
if(s[p][x+1]==s[q][i])
x++;
}
return x;
}
int main()
{
int n,i,j,k,sol=0,x=0,p=1,l;
f>>n;
for(i=1;i<=n;i++)
f>>(s[i]+1);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(i!=j&&kmp1(i,j)==0)
nu[i]=1;
for(i=1;i<=n;i++)
nu[i]+=nu[i-1];
for(i=1;i<=n;i++)
if(nu[i]==nu[i-1])
for(j=1;j<=n;j++)
if(nu[j]==nu[j-1])
if(i!=j)
cc[i][j]=kmp2(i,j),a[i].push_back({j,cc[i][j]});
for(i=1;i<=n-nu[n];i++)
p*=2;
p--;
for(i=0;i<=p;i++)
for(j=0;j<=n;j++)
dp[i][j]=-INF;
for(i=1;i<=n;i++)
if(nu[i]==nu[i-1])
dp[(1<<(i-nu[i]-1))][i]=0;
for(i=0;i<p;i++)
for(j=1;j<=n;j++)
if(nu[j]==nu[j-1])
if(dp[i][j]!=-INF)
{
l=a[j].size();
for(k=0;k<l;k++)
if((i&(1<<(a[j][k].x-nu[a[j][k].x]-1)))==0)
dp[i|(1<<(a[j][k].x-nu[a[j][k].x]-1))][a[j][k].x]=max(dp[i|(1<<(a[j][k].x-nu[a[j][k].x]-1))][a[j][k].x],dp[i][j]+a[j][k].c);//cout<<i<<" "<<j<<" "<<dp[i][j]<<" "<<(i|(1<<(a[j][k].x-nu[a[j][k].x]-1)))<<" "<<a[j][k].x<<" "<< dp[i|(1<<(a[j][k].x-nu[a[j][k].x]-1))][a[j][k].x]<<'\n';
}
for(i=1;i<=n;i++)
if(nu[i]==nu[i-1])
{
if(dp[p][i]>sol)
sol=dp[p][i],x=i;
}
v.push_back(x);
while(__builtin_popcount(p)!=1)
{
for(auto y:a[x])
if(((p&(1<<(x-nu[x]-1)))!=0)&&dp[(p^(1<<(x-nu[x]-1)))][y.x]==dp[p][x]-cc[y.x][x])
{
p=(p^(1<<(x-nu[x]-1))),x=y.x;
break;
}
v.push_back(x);
}
reverse(v.begin(),v.end());
l=strlen(s[v[0]]+1);
for(j=1;j<=l;j++)
g<<s[v[0]][j];
for(i=1;i<(int)v.size()-1;i++)
{
l=strlen(s[v[i]]+1);
for(j=cc[v[i-1]][v[i]]+1;j<=l;j++)
g<<s[v[i]][j];
}
l=strlen(s[v[v.size()-1]]+1);
for(j=cc[v[v.size()-2]][v[v.size()-1]]+1;j<=l;j++)
g<<s[v[v.size()-1]][j];
return 0;
}