题目链接

题意

给出一个长度字符串\(T\),其中只包含四种字符\((A,C,G,T)\),需要找一个字符串\(S\),使得\(S\)的长度为\(m\),问\(S\)和\(T\)的\(lcs\)为\(0,1,2...|T|\)时,分别有多少种情况。

\(|T| <= 15,m <= 1000\)

思路

考虑\(dp\)套\(dp\)(dp还能嵌套?)

先考虑已知S的情况下如何求\(lcs\)

用\(dp[i][j]\)表示\(S\)到了\(i\)位置,\(T\)到了\(j\)位置,最长公共子序列的长度。

那就有$$dp[i][j] = max(dp[i-1][j],dp[i][j-1]) \

if(S[i] == T[j]) \

dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1)$$

设计状态

用\(f[i][t_0][t_1][t_2]...[t_n]\)来表示\(S\)到了\(i\)位置,\(dp[i][0],dp[i][1],dp[i][2]...dp[i][n]\)分别为\(t_0,t_1,t_2,t_n\)的方案数。

然后发现时间和空间都会炸。所以考虑状压

根据求\(lcs\)的式子可以看出,\(dp[i][j]\)最多只会比\(dp[i][j-1]\)大\(1\),所以只要把f数组后面的数字差分一下,就变成了可以状压的状态。然后只要前缀和一下就可以还原这个数组。

所以用\(f[i][j]\)来表示\(S\)到了第\(i\)个位置,\(dp\)数组是\(j\)这个状态的方案数。

转移

先预处理出一个\(g\)数组,\(g[i][k]\)表示由\(i\)这个状态,下个位置是\(k\)这个字母,会转移成的状态。

这个预处理其实不难。只要先把i这个状态还原回来。然后用求\(lcs\)那个方法\(dp\)一下。最后再转化回去就可以了。

然后就是\(f\)数组的转移了,只要求出来了\(g\)数组,那么\(f\)数组就比较好处理了。

\[f[i][g[j][k]] += f[i - 1][j]
\]

复杂度是\(O(m2^{|T|})\)

代码

  1. /*
  2. * @Author: wxyww
  3. * @Date: 2019-01-20 10:33:34
  4. * @Last Modified time: 2019-01-20 11:40:43
  5. */
  6. #include<cstdio>
  7. #include<iostream>
  8. #include<cstdlib>
  9. #include<cmath>
  10. #include<cstring>
  11. #include<ctime>
  12. #include<bitset>
  13. using namespace std;
  14. typedef long long ll;
  15. const int N = 1<<15,mod = 1e9 + 7;
  16. ll read() {
  17. ll x=0,f=1;char c=getchar();
  18. while(c<'0'||c>'9') {
  19. if(c=='-') f=-1;
  20. c=getchar();
  21. }
  22. while(c>='0'&&c<='9') {
  23. x=x*10+c-'0';
  24. c=getchar();
  25. }
  26. return x*f;
  27. }
  28. char s[20];
  29. int f[1005][N];
  30. int n,tot,ss[20],tmp[2][20],sta[N][4];
  31. void pre(int x) {
  32. for(int i = 1;i <= n;++i) {
  33. tmp[0][i] = (x >> (n - i) & 1) + tmp[0][i - 1];
  34. }
  35. for(int k = 0;k <= 3;++k) {
  36. memset(tmp[1],0,sizeof(tmp[1]));
  37. for(int i = 1;i <= n;++i) {
  38. tmp[1][i] = max(tmp[0][i],tmp[1][i - 1]);
  39. if(ss[i] == k)
  40. tmp[1][i] = max(tmp[1][i],tmp[0][i - 1] + 1);
  41. }
  42. int z = 0;
  43. for(int i = 1;i <= n;++i)
  44. z = z << 1 | (tmp[1][i] - tmp[1][i - 1]);
  45. sta[x][k] = z;
  46. }
  47. }
  48. int ans[N];
  49. int calc(int x){
  50. int re = 0;
  51. while(x) {
  52. re += x & 1;
  53. x >>= 1;
  54. }
  55. return re;
  56. }
  57. int main() {
  58. int T = read();
  59. while(T--) {
  60. memset(f,0,sizeof(f));
  61. scanf("%s",s + 1);
  62. n = strlen(s + 1);
  63. int m = read();
  64. for(int i = 1;i <= n;++i) {
  65. if(s[i] == 'A') ss[i] = 0;
  66. else if(s[i] == 'C') ss[i] = 1;
  67. else if(s[i] == 'G') ss[i] = 2;
  68. else ss[i] = 3;
  69. }
  70. tot = (1 << n) - 1;
  71. f[0][0] = 1;
  72. for(int i = 0;i <= tot;++i) pre(i);
  73. for(int i = 1;i <= m;++i)
  74. for(int j = 0;j <= tot;++j)
  75. for(int k = 0;k < 4;++k)
  76. f[i][sta[j][k]] += f[i - 1][j],f[i][sta[j][k]] %= mod;
  77. memset(ans,0,sizeof(ans));
  78. for(int i = 0;i <= tot;++i) {
  79. int z = calc(i);
  80. ans[z] += f[m][i],ans[z] %= mod;
  81. }
  82. for(int i = 0;i <= n;++i) {
  83. printf("%d\n",ans[i]);
  84. }
  85. }
  86. return 0;
  87. }
  88. /*
  89. 2
  90. GTC
  91. 10
  92. GTC
  93. 10
  94. */

hdu4899 Hero meet devil的更多相关文章

  1. HDU4899 Hero meet devil DP套DP

    陈老师的题QwQ 原题链接 题目大意 有两个字符串\(S\)和\(T\)(都只能由'A','C','G','T'这四个字符组成),\(S\)已知\(T\)未知,还知道\(S\)的长度为\(m\).求满 ...

  2. bzoj 3864: Hero meet devil [dp套dp]

    3864: Hero meet devil 题意: 给你一个只由AGCT组成的字符串S (|S| ≤ 15),对于每个0 ≤ .. ≤ |S|,问 有多少个只由AGCT组成的长度为m(1 ≤ m ≤ ...

  3. 【BZOJ3864】Hero meet devil DP套DP

    [BZOJ3864]Hero meet devil Description There is an old country and the king fell in love with a devil ...

  4. BZOJ3864 & HDU4899:Hero meet devil——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3864 http://acm.hdu.edu.cn/showproblem.php?pid=4899 ...

  5. HDU 4899 Hero meet devil(状压DP)(2014 Multi-University Training Contest 4)

    Problem Description There is an old country and the king fell in love with a devil. The devil always ...

  6. bzoj3864: Hero meet devil

    Description There is an old country and the king fell in love with a devil. The devil always asks th ...

  7. BZOJ3864: Hero meet devil(dp套dp)

    Time Limit: 8 Sec  Memory Limit: 128 MBSubmit: 397  Solved: 206[Submit][Status][Discuss] Description ...

  8. BZOJ3864: Hero meet devil【dp of dp】

    Description There is an old country and the king fell in love with a devil. The devil always asks th ...

  9. DP套DP HDOJ 4899 Hero meet devil(国王的子民的DNA)

    题目链接 题意: 给n长度的S串,对于0<=i<=|S|,有多少个长度为m的T串,使得LCS(S,T) = i. 思路: 理解的不是很透彻,先占个坑. #include <bits/ ...

随机推荐

  1. .Net中EF通用数据层小结

    增删改查: using System; using System.Collections.Generic; using System.Data; using System.Data.Entity; u ...

  2. 创建安全客户端Socket

    SocketFactory factory = SSLSocketFactory.getDefault(); Socket socket = factory.create("localhos ...

  3. python之路--模块和包

    一 . 模块 ⾸先,我们先看⼀个老⽣常谈的问题. 什么是模块. 模块就是⼀个包含了python定义和声明的⽂件, ⽂件名就是模块的名字加上.py后缀. 换句话说我们⽬前写的所有的py⽂件都可以看成是⼀ ...

  4. EChart.js 笔记二

    交互组件 Echart.js 中交互组件比较多.例如: legend(图例).title(标题组件).visualMap(视觉映射组件).dataZoom(数据缩放组件).timeline(时间线组件 ...

  5. SQL 函数NULLIF、NULL、ISNULL、COALESCE、IIF

    NULLIF函数 NULLIF(Expression1,Expression2):给定两个参数Expression1和Expression2,如果两个参数相等,则返回NULL:否则就返回第一个参数. ...

  6. bmi

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. maven项目 报错 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):

    ssm的项目如果在mapper.xml  mapper接口 配置没问题的情况下  项目依然报org.apache.ibatis.binding.BindingException: Invalid bo ...

  8. AgilePoint数据库模式中当前所有表的列表

    表名 描述 WF_ACTIVITY_INSTS 包含有关活动实例的信息. WF_ASSIGNED_OBJECTS 包含有关用户角色的分配对象的信息. WF_AUDIT_TRAILS 包含有关流程模板的 ...

  9. codeforces492C

    Vanya and Exams CodeForces - 492C Vanya wants to pass n exams and get the academic scholarship. He w ...

  10. codeforces157B

    Trace CodeForces - 157B One day, as Sherlock Holmes was tracking down one very important criminal, h ...