Pagini recente » Cod sursa (job #1931920) | Cod sursa (job #713720) | Cod sursa (job #9778) | Cod sursa (job #380759) | Cod sursa (job #2538394)
#include <fstream>
#include <vector>
#include <cstring>
#define Nmax 19
#define Mmax 30001
using namespace std;
ifstream fin("adn.in");
ofstream fout("adn.out");
int n,m,stare[Mmax],marime[Nmax],dp[270001][Nmax],max1,venire[270001][Nmax],ret;
bool elim[Nmax];
vector <string> s;
struct NodCost{
int nod,cost;
};
vector <NodCost> G[Nmax];
int sol[Nmax],solm[Nmax][Nmax];
void KMP(int i,int j)
{
if (marime[i]<=marime[j])
{
memset(stare,0,sizeof stare);
int st=0,i1;
for (i1=2; i1<=marime[i]; i1++)
{
while (st>0 && s[i][st]!=s[i][i1-1])
st=stare[st];
if (s[i][st]==s[i][i1-1])
st++;
stare[i1]=st;
}
st=0;
for (i1=1; i1<=marime[j]; i1++)
{
while (st>0 && s[i][st]!=s[j][i1-1])
st=stare[st];
if (s[i][st]==s[j][i1-1])
st++;
if (st==marime[i])
{
elim[i]=1;
}
}
}
}
int KMP2(int i,int j)
{
memset(stare,0,sizeof stare);
int st=0,i1;
for (i1=2; i1<=marime[i]; i1++)
{
while (st>0 && s[i][st]!=s[i][i1-1])
st=stare[st];
if (s[i][st]==s[i][i1-1])
st++;
stare[i1]=st;
}
st=0;
for (i1=1; i1<=marime[j]; i1++)
{
while (st>0 && s[i][st]!=s[j][i1-1])
st=stare[st];
if (s[i][st]==s[j][i1-1])
st++;
if (i1==marime[j])
return st;
}
}
void hamilton(){
int stare,i,j;
for (stare=1; stare<=((1<<n)-1); stare++)
{
for (i=0; i<n; i++)
{
if (((1<<i) & stare)>0 && dp[stare][i]!=-1)
{
for (auto j:G[i])
{
if (((1<<j.nod) & stare)==0){
if (dp[stare+(1<<j.nod)][j.nod]<dp[stare][i]+j.cost){
dp[stare+(1<<j.nod)][j.nod]=dp[stare][i]+j.cost;
venire[stare+(1<<j.nod)][j.nod]=i;
}
}
}
}
}
}
}
void creare(int i,int j)
{
int x=KMP2(j,i);
G[i].push_back({j,x});
solm[i][j]=x;
}
int main()
{
int i,j;
fin>>n;
s.resize(n);
for (i=0; i<n; i++)
{
fin>> s[i];
marime[i]=s[i].size();
}
for (i=0; i<n; i++)
{
for (j=0; j<n; j++)
{
if (i!=j)
KMP(i,j);
}
}
i=n-1;
while (i>=0)
{
if (elim[i]==1)
{
s.erase(s.begin()+i);
n--;
}
i--;
}
for (i=0;i<n;i++)
marime[i]=s[i].size();
for (i=0; i<n; i++)
{
for (j=i+1; j<n; j++)
{
creare(i,j);
creare(j,i);
}
}
for (i=1;i<=(1<<n)-1;i++)
{
for (j=0;j<n;j++)
{
dp[i][j]=-1;
}
}
for (i=0;i<n;i++)
{
dp[1<<i][i]=0;
venire[1<<i][i]=-1;
}
hamilton();
max1=-1;
for (i=0; i<n; i++)
{
if(max1<dp[(1<<n)-1][i]){
max1=dp[(1<<n)-1][i];
ret=i;
}
}
int S=(1<<n)-1;
int nr=1;
sol[nr]=ret;
while (venire[S][ret]!=-1)
{
int o=ret;
ret=venire[S][ret];
S-=(1<<o);
nr++;
sol[nr]=ret;
}
for (i=nr;i>=2;i--)
{
int x=solm[sol[i]][sol[i-1]];
int y=s[sol[i]].size();
int x1=y-x;
for (int i1=0;i1<x1;i1++)
fout<<s[sol[i]][i1];
}
fout<<s[sol[1]];
return 0;
}