zoukankan      html  css  js  c++  java
  • hdu 3336 Count the string

    http://acm.hdu.edu.cn/showproblem.php?pid=3336

    hdu 3336 Count the string 【经典 KMP】+【DP】

    【题意】

    给你一个字符串,然后让你把所有的前缀给找出来,并把它们在字符串中的出现次数相加,输出这个和

    【分析】

    找出前缀后,算出现次数,很明显的是一个单模式串匹配问题,KMP 可以很好的解决,不过如果直接这样暴力的话,O(n^2) 的复杂度还是不行的。。。因此,我们试着考虑 KMP 算法进行快速匹配的本质核心所在,其实就是 next[] 数组

    而这个的本质其实就是 S[1..next[i]]=S[i-next[i]+1...i] 

    即模式串的最长公共前后缀串的长度

    举个例子 ababa 

    我们要算这个字符串的前缀的出现次数和

    a 出现 3 

    ab 出现 2

    aba 出现 2

    abab 出现 1

    ababa 出现 1

    那么我们可以这样来 DP 

    记 dp[i] 为前 i 个字符组成的前缀出现的次数

    则 dp[next[i]]+=dp[i] 

    这个转移方程是什么含义呢???

    我们可以这样来想

    如 dp[3] 对应 aba 且 next[5]=3

    则 dp[3]+=dp[5] 为答案

    因为  S[1..next[i]]=S[i-next[i]+1...i]  aba 自己出现了 dp[3] ,然后 S[i-next[i]+1..i] 出现了 dp[5] 也是 aba 会出现的地方,因此也要加上

    (还是要自己 YY 一下,这里说不清啊)

    初始化的时候,记得 dp[i]=1 表示自身匹配算 1 次


    今天就纠结这道题目,还学习了扩展KMP,可是因为那个太难了,所以大家都不太懂,所以我也很模糊。。。KMP今天继续做两题就over了,明天开始做dp,其实这道题目也是KMP+DP,上诉为参考资料。。。。

    #include <stdio.h>

    #include <string.h>

    #include <stdlib.h>

    int n,m,a[300000],next[300000];

    char s[300000];

    void getnext()

    {

         int i=0,j=-1;

         next[0]=-1;

         while(i<m)

         {

                if(j==-1||s[i]==s[j])

                {

                         ++i;++j;

                         next[i]=j;

                }   

                else

                j=next[j];

         }

    }

    int main()

    {

        scanf("%d",&n);

        while(n--)

        {

                  int sum=0;

                  scanf("%d",&m);

                  scanf("%s",s);

                  getnext();

                  memset(a,0,sizeof(a));

                  for(int i=1;i<=m;++i)

                  {

                        a[i]=(a[next[i]]+1)%10007;//这个地方是关键啊这里出来了,一切就 出来了

                        sum=(sum+a[i])%10007; 

                  }

                  printf("%d\n",sum);

        }

        return 0;

    }


  • 相关阅读:
    CALL FUNCTION 'BAPI_GOODSMVT_CREATE'-(物料凭证创建)
    SAP邮件
    sap人员编制
    ABAP 日期栏函数
    SAP建数据库索引
    去前导零
    SD相关的表
    php 使用 file_exists 还是 is_file
    FastAdmin 的 CRUD 不支持层级模型
    使用 Visual Studio Code (VSCODE)写 C51 (持续更新 2018-04-09)
  • 原文地址:https://www.cnblogs.com/yuelingzhi/p/2126346.html
Copyright © 2011-2022 走看看