• hdu3336 KMP + DP 前缀数组出现的次数


    题意:
          给你一个串,问你他的所有前缀子串在本串中的出现次数,注释:abc的前缀子串是
    a ab abc;


    思路:
         还是利用了next数组,先对子串求出next数组,再开一个数组dp,初始化全是1,因为每个以当前i结尾的都至少是1,然后从后往前更新,把以i结尾的加到以next[i]结尾的上,
    运用的next数组的特点相当于 123123123 最后一个3加到倒数第二个3,倒数第二个3再加到第一个3 那么以3结尾的(123)出现了三次,以3结尾的(123123)出现了两次,以3结尾的(123123123) 出现了一次。
    例子详细数据: 


    原串   123123123
    next   000123456
      dp   333222111


    提示:

        这个题目的串之间是可以交叉的,但不可以完全重叠,比如对与这个题目11111的答案是15.


    #include<stdio.h>
    #include<string.h>
    
    #define N 200000 + 100
    
    char str[N];
    int next[N];
    int dp[N];
    
    void get_next(int m)
    {
       int j ,k;
       j = 0 ,k = -1;
       next[0] = -1;
       while(j < m)
       {
          if(k == -1 || str[j] == str[k])
          next[++j] = ++k;
          else k = next[k];
       }
       return ;
    }
    
    int main ()
    {
       int t ,m ,i;
       scanf("%d" ,&t);
       while(t--)
       {
          scanf("%d" ,&m);
          scanf("%s" ,str);
          get_next(m);
          for(i = 1 ;i <= m ;i ++)
          dp[i] = 1;
          int sum = 0;
          for(i = m ;i >= 1 ;i --)
          {
             if(next[i])
             {
                dp[next[i]] += dp[i];
                dp[next[i]] %= 10007;
             }
             sum += dp[i];
             sum %= 10007;
          }
          /*
          for(i = 1 ;i <= m ;i ++)
          printf("%d " ,next[i]);
          printf("
    ");
          for(i = 1 ;i <= m ;i ++)
          printf("%d " ,dp[i]);
          printf("
    ");
          */
          printf("%d
    " ,sum);
       }
       return 0;
    }
    
    
    

  • 相关阅读:
    剑指OFFER 滑动窗口的最大值
    剑指OFFER 正则表达式匹配
    linux动态链接库的使用
    剑指OFFER 序列化二叉树
    剑指OFFER 数字在排序数组中出现的次数
    剑指OFFER 数组中的逆序对
    剑指OFFER 反转链表
    剑指OFFER 二叉树的深度
    剑指OFFER 矩形覆盖
    网络相关的命令工具-iptables
  • 原文地址:https://www.cnblogs.com/csnd/p/12063109.html
Copyright © 2020-2023  润新知