最短母串 bzoj-1195 HNOI-2006

题目大意:给一个包含n个字符串的字符集,求一个字典序最小的字符串使得字符集中所有的串都是该串的子串。

注释:$1\le n\le 12$,$1\le max length \le 50$。

想法:刚开始在那里AC自动机半天,然后瞅了一眼数据范围... ...状压吧兄弟!!

首先,我们先做一些预处理:把可以被字符集中串包含的串都删掉;求出两个字符串连接后的长度(这个预处理暴力即可),设merge[i][j]表示串i和串j合并后的长度。

状态:dp[s][i]表示这个串已经包含了s状态的字符串且紧跟着的串是i的最短长度。

转移:dp[s][i]=min{dp[s^(1<<(j+1))][j]+merge[i][j]-length(j)};

最后,附上丑陋的代码... ...

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<queue>
  6. using namespace std;
  7. const int INF=0x3f3f3f3f;
  8. const int mxn=61;
  9. int n;
  10. struct bind
  11. {
  12. char s[605];
  13. int len;
  14. bool operator < (const bind y) const
  15. {
  16. if(len!=y.len)return len<y.len;
  17. for(int i=0;i<len;i++)
  18. if(s[i]!=y.s[i])return s[i]<y.s[i];
  19. return 0;
  20. }
  21. }f[1<<12][12],s[12];
  22. int c[13][13];
  23. bool ban[mxn];
  24.  
  25. bool ovl(int i,int j)
  26. {
  27. if(s[i].len<s[j].len)return 0;
  28. char *p=strstr(s[i].s,s[j].s);
  29. if(p==NULL)return 0;
  30. return 1;
  31. }
  32. int clc(int x,int y)
  33. {
  34. bool flag=0;
  35. for(int i=max(0,s[x].len-s[y].len);i<s[x].len;i++)
  36. {
  37. flag=1;
  38. for(int j=i;j<s[x].len;j++)
  39. if(s[x].s[j]!=s[y].s[j-i]){flag=0;break;}
  40. if(flag)return s[x].len-i;
  41. }
  42. return 0;
  43. }
  44. bind merge(int S,int u,int v)
  45. {
  46. bind tmp=f[S][u];
  47. strcat(tmp.s,s[v].s+c[u][v]);
  48. tmp.len=f[S][u].len-c[u][v]+s[v].len;
  49. return tmp;
  50. }
  51. void Dp()
  52. {
  53. int i,j,ed=(1<<n)-1;
  54. for(i=0;i<=ed;i++)
  55. for(j=0;j<n;j++)f[i][j].len=INF;
  56. for(i=0;i<n;i++)f[1<<i][i]=s[i];
  57. for(i=1;i<=ed;i++)
  58. {
  59. for(j=0;j<n;j++)
  60. {
  61. if((i>>j)&1)
  62. for(int k=0;k<n;k++)
  63. {
  64. if((i>>k)&1) continue;
  65. bind tmp=merge(i,j,k);
  66. if(tmp<f[i|(1<<k)][k])f[i|(1<<k)][k]=tmp;
  67. }
  68. }
  69. }
  70. }
  71. int main()
  72. {
  73. scanf("%d",&n);
  74. for(int i=0;i<n;i++)scanf("%s",s[i].s),s[i].len=strlen(s[i].s);
  75. for(int i=0;i<n;i++)
  76. for(j=0;j<n;j++)
  77. if(i!=j && ovl(i,j) && !ban[i])ban[j]=1;
  78. int cnt=0;
  79. for(int i=0;i<n;i++)if(!ban[i])s[cnt++]=s[i];
  80. n=cnt;
  81. for(int i=0;i<n;i++)
  82. for(int j=0;j<n;j++)
  83. if(i!=j)c[i][j]=clc(i,j);
  84. Dp();
  85. int ans=0,ed=(1<<n)-1;
  86. for(int i=1;i<n;i++)
  87. if(f[ed][i]<f[ed][ans])ans=i;
  88. printf("%s",f[ed][ans].s);
  89. return 0;
  90. }

小结:看到了数据做题是一种解题想法,但是考试的时候看数据范围猜复杂度我tm就没成功过... ...

[bzoj1195][HNOI2006]最短母串_动态规划_状压dp的更多相关文章

  1. [HNOI2006]最短母串问题——AC自动机+状压+bfs环形处理

    Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. 32MB Input 第一行是一个正整数n(n< ...

  2. BZOJ1195[HNOI2006]最短母串——AC自动机+BFS+状态压缩

    题目描述 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. 输入 第一行是一个正整数n(n<=12),表示给定的字符串的 ...

  3. Bzoj1195 [HNOI2006]最短母串 [状态压缩]

    Time Limit: 10 Sec  Memory Limit: 32 MBSubmit: 1304  Solved: 439 Description 给定n个字符串(S1,S2,„,Sn),要求找 ...

  4. BZOJ1195 [HNOI2006]最短母串 【状压dp】

    题目 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. 输入格式 第一行是一个正整数n(n<=12),表示给定的字符串的 ...

  5. Bzoj1195 [HNOI2006]最短母串 [AC自动机]

    Time Limit: 10 Sec  Memory Limit: 32 MBSubmit: 1304  Solved: 439 Description 给定n个字符串(S1,S2,„,Sn),要求找 ...

  6. BZOJ1195 [HNOI2006]最短母串 AC自动机 bfs

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 传送门 - BZOJ1195 题意概括 给出一堆串,然后求一个包含这些串的所有串的最短的中的字典序最小的. 题解 先造一个AC ...

  7. BZOJ1195 HNOI2006最短母串(状压dp)

    按照子串出现的先后考虑.令f[i][j]为已经出现的字符串集合为i,最后一个出现的字符串为j时的最短串长,预处理一下任意两个串的最长重叠长度,转移显然.有点麻烦的是字典序,强行增加代码难度. 另一个比 ...

  8. [BZOJ1195]:[HNOI2006]最短母串(AC自动机+BFS)

    题目传送门 题目描述 给定n个字符串(S1,S2,…,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,…,Sn)都是T的子串. 输入格式 第一行是一个正整数n,表示给定的字符串的个数 ...

  9. BZOJ1195: [HNOI2006]最短母串(Trie图,搜索)

    Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. Input 第一行是一个正整数n(n<=12) ...

随机推荐

  1. 针对深度学习(神经网络)的AI框架调研

    针对深度学习(神经网络)的AI框架调研 在我们的AI安全引擎中未来会使用深度学习(神经网络),后续将引入AI芯片,因此重点看了下业界AI芯片厂商和对应芯片的AI框架,包括Intel(MKL CPU). ...

  2. [NOIP 2016] 蚯蚓

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=4721 [算法] 首先,我们可以维护一个堆,堆中存放蚯蚓的长度,由于除当前蚯蚓其他的蚯 ...

  3. bzoj 1026 [ SCOI2009 ] windy数 —— 数位DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1026 蛮简单的数位DP,预处理 f[i][j] 表示 i 位数,以 j 开头的 windy ...

  4. 使用pycharm进行简单的数据库管理

    功能简介 pycharm自带了一个简单的数据库插件,可以比较方便的进行简单的数据库操作. 例如: 1.创建,修改和删除数据表,字段,索引,主键,外键等. 2.提供table editor来进行数据操作 ...

  5. 前端面试准备之JavaScript

    1.数据类型. JavaScript中有5种简单数据类型(也称为基本数据类型):Undefined.Null.Boolean.Number和String.还有1种复杂数据类型——Object,Obje ...

  6. (Go)09.指针赋值修改示例

      答案: 1 package main 2 import ( 3 "fmt" 4 ) 5 6 7 func modify(p *int) { 8 fmt.Println(p) 9 ...

  7. Android PopWindow的替代品BasePopup

    版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/109 背景描述 最近一段时间,又看到了这个开源项目Base ...

  8. 【POJ2248、LOJ#10021】 Addition Chains

    事先预警:由于我太蒻了,本做法只能在POJ.LOJ等小数据(N<=100)平台上通过,在UVa(洛谷)上大数据并不能通过 戳我获得更好的观看效果 本题不用看,爆搜就是了,但是纯爆搜显然会爆时间, ...

  9. MySQL安装for windows

    ======MySQL安装 for windows====== 版本5.7.X MySQL服务器帮助我们来管理文件的操作 MySQL软件 - 服务器端软件 - 服务端程序 - 解析指令 - 对文件的操 ...

  10. 5.29 @Value{name}无效时怎么办Could not resolve placeholder ‘name22’ in value “${name22}” 错误解决

    springboot Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder ‘name22’ in ...