mirror of
https://github.com/Kiritow/OJ-Problems-Source.git
synced 2024-03-22 13:11:29 +08:00
e7ac37406c
3800-3899
154 lines
3.6 KiB
C++
154 lines
3.6 KiB
C++
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <string>
|
|
#include <stdlib.h>
|
|
#include <vector>
|
|
#include <math.h>
|
|
#include <algorithm>
|
|
#include <iostream>
|
|
#define N 16
|
|
#define M 1<<16
|
|
#define MS 1000000009
|
|
#define LL long long
|
|
using namespace std;
|
|
int n,goal;
|
|
string str[N];
|
|
LL da[N];
|
|
int gra[N][N],mark[N];
|
|
int slen[N];
|
|
int dp[M][N];
|
|
LL ans;
|
|
void ini(void)
|
|
{
|
|
goal=(1<<n)-1;
|
|
for(int i=0;i<n;i++)
|
|
str[i].clear();
|
|
for(int i=0;i<n;i++)
|
|
{
|
|
LL k=da[i];
|
|
while(k)
|
|
{
|
|
str[i].push_back((k&1)+'0');
|
|
k=k>>1;
|
|
}
|
|
int j=str[i].size();
|
|
string tempstr;
|
|
while(j--)
|
|
tempstr.push_back(str[i][j]);
|
|
str[i]=tempstr;
|
|
}
|
|
sort(str,str+n);
|
|
for(int i=0;i<n;i++)
|
|
slen[i]=str[i].size();
|
|
memset(mark,0,sizeof(mark));
|
|
for(int i=0;i<n;i++)
|
|
for(int j=0;j<n;j++)
|
|
if(i!=j&&slen[i]>slen[j])
|
|
for(int k1=0;k1<slen[i]-slen[j]+1;k1++)
|
|
{
|
|
int flag=0;
|
|
for(int k2=0;k2<slen[j];k2++)
|
|
if(str[i][k1+k2]!=str[j][k2])
|
|
{
|
|
flag=1;
|
|
break;
|
|
}
|
|
if(flag==0)
|
|
{
|
|
if(!mark[j])
|
|
{
|
|
mark[j]=1;
|
|
goal-=(1<<j);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
for(int i=0;i<n-1;i++)
|
|
for(int j=i+1;j<n;j++)
|
|
if(!mark[i]&&!mark[j]&&str[i]==str[j])
|
|
mark[j]=1,goal-=(1<<j);
|
|
memset(gra,0,sizeof(gra));
|
|
for(int i=0;i<n;i++)
|
|
for(int j=0;j<n;j++)
|
|
if(!mark[i]&&!mark[j]&&i!=j)
|
|
for(int k=0;k<slen[i];k++)
|
|
{
|
|
int flag=0;
|
|
for(int u=0;u+k<slen[i];u++)
|
|
if(str[i][k+u]!=str[j][u])
|
|
{
|
|
flag=1;
|
|
break;
|
|
}
|
|
if(!flag)
|
|
{
|
|
gra[i][j]=slen[i]-k;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
void dfs(int s,int p)
|
|
{
|
|
if(~dp[s][p])return ;
|
|
if(s==(1<<p))
|
|
{
|
|
dp[s][p]=slen[p];
|
|
return ;
|
|
}
|
|
int minn=0x3f3f3f3f;
|
|
int t=s-(1<<p);
|
|
for(int i=0;i<n;i++)
|
|
if(!mark[i]&&i!=p&&(s&(1<<i)))
|
|
{
|
|
dfs(t,i);
|
|
minn=min(minn,dp[t][i]-gra[p][i]);
|
|
}
|
|
dp[s][p]=minn+slen[p];
|
|
}
|
|
void rans(int s,int p,int e)
|
|
{
|
|
for(int i=e;i<slen[p];i++)
|
|
ans=(ans*2+str[p][i]-'0')%MS;
|
|
if(s==(1<<p))return ;
|
|
int t=s-(1<<p);
|
|
int k=-1;
|
|
string a;
|
|
for(int i=0;i<n;i++)
|
|
if(!mark[i]&&(s&(1<<i))&&dp[t][i]-gra[p][i]+slen[p]==dp[s][p])
|
|
{
|
|
string b(str[i],gra[p][i],slen[p]-gra[p][i]);
|
|
if(k==-1||a>b)
|
|
a=b,k=i;
|
|
}
|
|
rans(t,k,gra[p][k]);
|
|
}
|
|
void re(void)
|
|
{
|
|
for(int i=0;i<n;i++)
|
|
scanf("%lld",&da[i]);
|
|
}
|
|
void run(void)
|
|
{
|
|
ini();
|
|
memset(dp,-1,sizeof(dp));
|
|
for(int i=0;i<n;i++)
|
|
if(!mark[i])
|
|
dfs(goal,i);
|
|
int p,minn=0x3f3f3f3f;
|
|
for(int i=0;i<n;i++)
|
|
if(!mark[i]&&dp[goal][i]<minn)
|
|
p=i,minn=dp[goal][i];
|
|
ans=0;
|
|
rans(goal,p,0);
|
|
printf("%lld\n",ans);
|
|
}
|
|
int main()
|
|
{
|
|
while(scanf("%d",&n)!=EOF)
|
|
{
|
|
re();
|
|
run();
|
|
}
|
|
return 0;
|
|
}
|