zoukankan      html  css  js  c++  java
  • HDU 3336 Count the string (KMP+DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3336

    题目大意:给出一串字符串s,求出所有s的前缀在s中出现次数之和。

    解题思路:

    利用cnt[i]记录子串0~i共含有以b[i]为结尾的前缀的数目,得到状态转移方程:cnt[i]=cnt[next[i]]+1。

    大概说一下我的理解吧,为什么是cnt[i]是表示以b[i]为结尾的前缀数量,因为从0~m递推过来b[i]作为在b[i-1]
    后新出现的字符,cnt[i]记录的就是因b[i]出现后产生的前缀数量(跟b[i]的出现有关联的),首先肯定会包含的前缀就是0~i,还有0~next[i],那么
    就是cnt[i]=cnt[next[i]]+1。

    代码

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 const int N=1e6+5;
     7 const int MOD=10007;
     8 
     9 int m;
    10 int nxt[N],cnt[N];
    11 char p[N];
    12 
    13 void getnext(){
    14     int i,j;
    15     i=0,j=nxt[0]=-1;
    16     while(i<m){
    17         while(j!=-1&&p[i]!=p[j])
    18             j=nxt[j];
    19         nxt[++i]=++j;
    20     }
    21 }
    22 
    23 int main(){
    24     int t;
    25     scanf("%d",&t);
    26     while(t--){
    27         scanf("%d%s",&m,p);
    28         getnext();
    29         cnt[0]=0;
    30         int sum=0;
    31         //cnt[i]=cnt[next[i]]+1;
    32         for(int i=1;i<=m;i++){
    33             cnt[i]=cnt[nxt[i]]+1;
    34             sum=(sum+cnt[i])%MOD;
    35         }
    36         printf("%d
    ",sum);
    37     }
    38     return 0;
    39 }
  • 相关阅读:
    学期总结
    Sprint 2(第一天)
    学期总结
    实验四、主存空间的分配和回收
    阅读《构建之法》与链接有感.
    《构建之法》八、九、十章读后感
    Scrum领取任务
    实验三、进程调度模拟程序实验
    《构建之法》6-7章读后感
    实验二 作业调度模拟程序
  • 原文地址:https://www.cnblogs.com/fu3638/p/8491175.html
Copyright © 2011-2022 走看看