1 条题解
-
0
C++ :
#include<cstdio> const int N=12,inf=120; int n,S,i,j,k,l,L,x,y,a[N][N],suf[N][N],len[N];bool g[N][N][N]; char f[1<<10][N][N][N][N],t,ans=inf; inline bool check(int A,int B,int C){ int i; for(B++,i=1;i<=len[C]&&B<=len[A];i++)if(a[A][B]==a[C][i])B++; if(B<=len[A])return 0; for(i=1;i<=len[C];i++)if(!(suf[A][1]>>a[C][i]&1))return 0; return 1; } inline void up(char&x,char y){if(x>y)x=y;} int main(){ scanf("%d",&n); for(i=1;i<=n;i++){ while(1){ scanf("%d",&x); if(!x)break; a[i][++len[i]]=x-1; } for(j=len[i];j;j--)suf[i][j]=suf[i][j+1]|(1<<a[i][j]); } for(i=1;i<=n;i++)g[0][0][i]=1; for(i=1;i<=n;i++)for(j=0;j<=len[i];j++)for(k=1;k<=n;k++)g[i][j][k]=check(i,j,k); for(S=0;S<1<<n;S++)for(i=0;i<=n;i++)for(j=1;j<=len[i]+1;j++) for(k=0;k<=n;k++)for(l=0;l<=len[k];l++)f[S][i][j][k][l]=inf; for(i=1;i<=n;i++)f[1<<(i-1)][i][len[i]+1][0][0]=0; for(S=1;S<1<<n;S++)for(i=n;~i;i--)for(j=len[i]+1;j;j--) for(k=0;k<=n;k++)for(l=0;l<=len[k];l++)if(f[S][i][j][k][l]<inf){ t=f[S][i][j][k][l]; for(x=1;x<=n;x++)if(!(S>>(x-1)&1)&&g[k][l][x])up(f[S|(1<<(x-1))][i][j][x][0],t); if(i&&j==1){ for(x=1;x<=n;x++)if(!(S>>(x-1)&1)) for(y=0;y<=len[x];y++)if(g[x][y][i]) up(f[S|(1<<(x-1))][x][y+1][k][l],t); up(f[S][0][1][k][l],t); } t++; if(j>1)for(x=0;x<9;x++){ if(!(suf[i][1]>>x&1))continue; if(suf[i][j]>>x&1)continue; if(k){ if(!(suf[k][1]>>x&1))continue; if(suf[k][l+2]>>x&1)continue; } L=l; if(l<len[k]&&x==a[k][l+1])L++; up(f[S][i][j][k][L],t); if(x==a[i][j-1])up(f[S][i][j-1][k][L],t); } if(!i)for(x=0;x<9;x++){ if(k){ if(!(suf[k][1]>>x&1))continue; if(suf[k][l+2]>>x&1)continue; } L=l; if(l<len[k]&&x==a[k][l+1])L++; up(f[S][i][j][k][L],t); } } for(i=0;i<=n;i++)for(k=0;k<=n;k++)up(ans,f[(1<<n)-1][i][1][k][len[k]]); return printf("%d",ans<inf?ans:-1),0; }
- 1
信息
- ID
- 1041
- 时间
- 5000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 0
- 上传者