DNA Sequence LightOJ
来源:互联网 发布:3d studio max mac版 编辑:程序博客网 时间:2024/05/21 12:49
题面
题意
给出n个字符串,找到一个字符串使它包含以上所有字符串.
方法
因为n<=15,所以用状压dp,首先预处理:
1.去掉包含字符串
2.排序,可以根据字符串的序号直接得到字典序的先后
3.求出任意两个字符串衔接在一起所重叠的字符个数.之后进行dp,若更新的长度较小则直接更新,反之比较字典序
因为从头开始遍历时,比较字典序十分麻烦(要全部展开),故从后面向前遍历.
dp数组记录状态和前缀不用考虑两个字符串合并后包含了另一个字符串,因为一定存在一种最优解不会发生此种情况,例如:
若a,b和并后包含了c
则可由a先和c合并,再和b合并得到.
代码
从前向后(TLE)
#include<bits/stdc++.h>#define M 40000#define N 20using namespace std;int dp[M][N],pri[M][N],n,T,TT,zh[N][N],len[N],mn;char a[N][110],tmp[2010],ans[2010];inline void shch(int u){ int i; for(i=u;i<=n;i++) { swap(a[i],a[i+1]); len[i]=len[i+1]; } n--;}inline bool pd(int u,int v){ int i,j; if(len[u]<len[v]) swap(u,v); for(i=1;i<=len[u]-len[v]+1;i++) { for(j=1;j<=len[v];j++) { if(a[v][j]!=a[u][j+i-1]) break; if(j==len[v]) { shch(v); return 1; } } } return 0;}inline int Zh(int u,int v){ int i,j; char ch; ch=a[u][len[u]]; for(i=min(len[v]-1,len[u]-1);i>=1;i--) { if(a[v][i]==ch) { for(j=1;j<=i;j++) { if(a[u][len[u]-j+1]!=a[v][i-j+1]) break; if(j==i) { return i; } } } } return 0;}inline bool cmp2(int zt,int u,int v){ int i,j,n1[N],n2[N],nn,now,uu,last; string p="",q=""; nn=0; now=zt; while(u!=-1) { nn++; n1[nn]=u; uu=u; u=pri[now][u]; now^=(1 << (uu-1)); } nn=0; now=zt; while(v!=-1) { nn++; n2[nn]=v; uu=v; v=pri[now][v]; now^=(1 << (uu-1)); } if(n1[nn]<n2[nn]) return 1; if(n1[nn]>n2[nn]) return 0; for(i=nn;i>=2;i--) { for(j=1;j<=len[n1[i]]-zh[n1[i]][n1[i-1]];j++) { p+=a[n1[i]][j]; } } for(i=1;i<=len[n1[1]];i++) { p+=a[n1[1]][i]; } for(i=nn;i>=2;i--) { for(j=1;j<=len[n2[i]]-zh[n2[i]][n2[i-1]];j++) { q+=a[n2[i]][j]; } } for(i=1;i<=len[n2[1]];i++) { q+=a[n2[1]][i]; } if(p<q) return 1; return 0;}inline void find(int u){ int uu,nn=0,num[N],now=(1 << n)-1,i,j; while(u!=-1) { nn++; num[nn]=u; uu=u; u=pri[now][u]; now^=(1 << (uu-1)); } now=0; for(i=nn;i>=2;i--) { for(j=1;j<=len[num[i]]-zh[num[i]][num[i-1]];j++) { now++; tmp[now]=a[num[i]][j]; } } for(i=1;i<=len[num[1]];i++) { now++; tmp[now]=a[num[1]][i]; } for(i=1;i<=mn;i++) { if(ans[i]<tmp[i]) return; if(ans[i]>tmp[i]) break; } for(i=1;i<=mn;i++) { ans[i]=tmp[i]; }}void cmp3(int u,int v){ int i; for(i=1;i<=min(len[u],len[v]);i++) { if(a[u][i]>a[v][i]) { swap(a[u],a[v]); } if(a[u][i]<a[v][i]) return; }}int main(){ int i,j,k; cin>>T; TT=T; while(T--) { scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%s",a[i]+1); len[i]=strlen(a[i]+1); } for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(i==j) continue; if(pd(i,j)) { j--; } } } for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(i==j) continue; zh[i][j]=Zh(i,j); } } for(i=1;i<=n-1;i++) { for(j=1;j<=n-1;j++) { cmp3(j,j+1); } } for(i=1;i<=n;i++) { for(j=1;j<=(1 << n)-1;j++) { dp[j][i]=M; } } for(i=1;i<=n;i++) { dp[(1 << (i-1))][i]=len[i]; pri[(1 << (i-1))][i]=-1; } for(i=1;i<(1 << n)-1;i++) { for(j=1;j<=n;j++)//ºó׺Ϊj { if(dp[i][j]==M||!((1 << (j-1))&i)) continue; for(k=1;k<=n;k++)//мÓÈëÔªËØΪk { if((i&(1 << (k-1)))) continue; if(dp[i|(1 << (k-1))][k]>dp[i][j]+len[k]-zh[j][k]) { dp[i|(1 << (k-1))][k]=dp[i][j]+len[k]-zh[j][k]; pri[i|(1 << (k-1))][k]=j; } else if(dp[i|(1 << (k-1))][k]==dp[i][j]+len[k]-zh[j][k]&&cmp2(i,j,pri[i|(1 << (k-1))][k])) { pri[i|(1 << (k-1))][k]=j; } } } } mn=M; for(i=1;i<=n;i++) { mn=min(mn,dp[(1 << n)-1][i]); } ans[1]='z'; for(i=1;i<=n;i++) { if(dp[(1 << n)-1][i]==mn) { find(i); } } printf("Case %d: ",TT-T); for(i=1;i<=mn;i++) { printf("%c",ans[i]); } printf("\n"); }}
从后向前(AC)
#include<bits/stdc++.h>#define M 40000#define N 20using namespace std;int dp[M][N],pri[M][N],n,T,TT,zh[N][N],len[N],mn;char a[N][110],tmp[2010],ans[2010];inline void shch(int u){ int i; for(i=u;i<=n;i++) { swap(a[i],a[i+1]); len[i]=len[i+1]; } n--;}inline bool pd(int u,int v){ int i,j; if(len[u]<len[v]) swap(u,v); for(i=1;i<=len[u]-len[v]+1;i++) { for(j=1;j<=len[v];j++) { if(a[v][j]!=a[u][j+i-1]) break; if(j==len[v]) { shch(v); return 1; } } } return 0;}inline int Zh(int u,int v){ int i,j; char ch; ch=a[u][len[u]]; for(i=min(len[v]-1,len[u]-1);i>=1;i--) { if(a[v][i]==ch) { for(j=1;j<=i;j++) { if(a[u][len[u]-j+1]!=a[v][i-j+1]) break; if(j==i) { return i; } } } } return 0;}bool cmp2(int u,int v,int last){ int i,j; for(j=zh[last][v]+1,i=zh[last][u]+1;i<=len[u]&&j<=len[v];i++,j++) { if(a[u][i]>a[v][j]) return 0; if(a[u][i]<a[v][j]) return 1; }}void cmp3(int u,int v){ int i; for(i=1;i<=min(len[u],len[v]);i++) { if(a[u][i]>a[v][i]) { swap(a[u],a[v]); swap(len[u],len[v]); } if(a[u][i]<a[v][i]) return; }}void find(int u){ int now=(1 << n)-1,i,j,num[N],nn=0,uu; while(u!=-1) { nn++; num[nn]=u; uu=u; u=pri[now][u]; now^=(1 << (uu-1)); } now=0; for(i=1;i<=len[num[1]];i++) { now++; ans[now]=a[num[1]][i]; } for(i=2;i<=nn;i++) { for(j=zh[num[i-1]][num[i]]+1;j<=len[num[i]];j++) { now++; ans[now]=a[num[i]][j]; } }}int main(){ int i,j,k; cin>>T; TT=T; while(T--) { scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%s",a[i]+1); len[i]=strlen(a[i]+1); } for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(i==j) continue; if(pd(i,j)) { j--; } } } for(i=1;i<=n-1;i++) { for(j=1;j<=n-1;j++) { cmp3(j,j+1); } } for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(i==j) continue; zh[i][j]=Zh(i,j); } } /* for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { cout<<zh[i][j]<<" "; } cout<<endl; } //*/ for(i=1;i<=n;i++) { for(j=1;j<=(1 << n)-1;j++) { dp[j][i]=M; } } for(i=1;i<=n;i++) { dp[(1 << (i-1))][i]=len[i]; pri[(1 << (i-1))][i]=-1; }// continue; //´ÓºóÍùÇ° for(i=1;i<(1 << n)-1;i++) { for(j=1;j<=n;j++)//¼ÓÈëj { if(((1 << (j-1))&i)) continue; for(k=1;k<=n;k++)//ǰ׺Ϊk { if(!((1 << (k-1)&i))) continue; if(dp[i|(1 << (j-1))][j]>dp[i][k]+len[j]-zh[j][k]) { dp[i|(1 << (j-1))][j]=dp[i][k]+len[j]-zh[j][k]; pri[i|(1 << (j-1))][j]=k; } else if(dp[i|(1 << (j-1))][j]==dp[i][k]+len[j]-zh[j][k]&&cmp2(k,pri[i|(1 << (j-1))][j],j)) { pri[i|(1 << (j-1))][j]=k; } } } } mn=M; int an; for(i=1;i<=n;i++) { if(mn>dp[(1 << n)-1][i]) { mn=dp[(1 << n)-1][i]; an=i; } }// cout<<mn;// cout<<an; find(an); printf("Case %d: ",TT-T); for(i=1;i<=mn;i++) { printf("%c",ans[i]); } printf("\n"); }}
阅读全文
1 0
- DNA Sequence LightOJ
- LightOJ 1073 DNA Sequence (状压DP+字符串比较)
- DNA sequence
- LightOJ 1224 DNA Prefix
- poj 2778 DNA Sequence
- POJ 2778 DNA Sequence
- poj 2778 DNA Sequence
- Poj 2778 DNA Sequence
- HDU - 1560 DNA sequence
- POJ 2778 DNA Sequence
- POJ 2778 DNA Sequence
- POJ 2778 DNA Sequence
- POJ2778 DNA Sequence
- HDU1560:DNA sequence(IDA*)
- hdu1560 DNA sequence (IDA*)
- [leetcode] Repeated DNA sequence
- Leetcode: Repeated DNA Sequence
- poj-2778 DNA Sequence
- Wannafly挑战赛2 B Travel(dij)
- c++的虚函数使用
- java1.8 常用集合源码学习:TreeMap
- Ubuntu下杀掉进程
- python基础班学习-day1
- DNA Sequence LightOJ
- 分布式事物管理
- Uber终于消停了,新CEO说要带飞
- java1.8 常用集合源码学习:TreeSet
- 【思维】AtCoder Grand Contest(013)C[Ants on a Circle]题解
- 关于Shell的实用技巧分享
- 动态规划之小偷打劫房间
- 15nod1572-模拟&前缀和&枚举-宝岛地图
- 近期任务规划