设为首页 加入收藏

TOP

Light OJ 1334 Genes in DNA KMP+DP
2015-07-24 06:38:46 来源: 作者: 【 】 浏览:70
Tags:Light 1334 Genes DNA KMP

题目来源:Light OJ 1334 Genes in DNA

题意:输入文本串和模式串 模式串的前缀和后缀组成(n-1)*(n-1)个组合 求模式串的子串出现多少次前后缀组合 一个子串可以对应多个组合串

思路:既然是前缀和后缀的组合 很好想到正反求2次KMP 枚举相邻的2个字符 i,j 答案就是若干以i结尾的前缀数量乘以j为开始的后缀数量的积的和

求到i字符为止的前缀数量和HDU 3336差不多 有点DP的思想

求以j字符开始的后缀数就是发过来 然后和求前缀一样的

#include 
  
   
#include 
   
     #include 
    
      #include 
     
       using namespace std; const int maxn = 50010; int l[maxn], r[maxn], f[maxn]; int dp1[maxn], dp2[maxn]; char s1[maxn], s2[maxn]; void getFail(char *p, int *dp) { int m = strlen(p); f[0] = f[1] = 0; dp[0] = 0; dp[1] = 1; for(int i = 1; i < m; i++) { int j = f[i]; while(j && p[i] != p[j]) j = f[j]; f[i+1] = p[i] == p[j] ? j+1 : 0; dp[i+1] = p[i] == p[j] ? dp[j+1]+1 : 1; } } void find(char *s1, char* s2, int* dp, int* a) { int cnt = 0; int j = 0; int n = strlen(s1); int m = strlen(s2); for(int i = 0; i < n; i++) { while(j && s1[i] != s2[j]) j = f[j]; if(s1[i] == s2[j]) j++; a[i+1] = dp[j]; if(j == m) { a[i+1]--; j = f[j]; } } } int main() { int cas = 1; int T; scanf("%d", &T); while(T--) { scanf("%s %s", s1, s2); int n = strlen(s1); int m = strlen(s2); getFail(s2, dp1); find(s1, s2, dp1, l); reverse(s1, s1+n); reverse(s2, s2+m); getFail(s2, dp2); find(s1, s2, dp2, r); long long ans = 0; for(int i = 1; i < n; i++) { ans += (long long)l[i]*r[n-i]; } printf("Case %d: %lld\n", cas++, ans); } return 0; }
     
    
   
  




】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇hdu(2062)-Subset sequence 组合.. 下一篇设计模式C++实现――工厂方法模式

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: