zoukankan      html  css  js  c++  java
  • HDU 5763 Another Meaning (KMP/哈希+DP)

    题目大意:给你两个串,一长一短,如果长串中某个子串和短串完全相同,则这个子串可以被替换成"#",求长串所有的表达形式.......

    比如"hehehehe"和"hehe",则有5种情况,"#hehe","he#he","hehe#","##","hehehehe"

    首先我们KMP/哈希找出长串中所有可以作为和短串结尾匹配成功后的位置

    然后可以得到方程

    f[i]=f[i-1]                         (不是子串结尾)

    f[i]=f[i-1]+f[i-len]  (是子串结尾)

    至于原因呢,如果它不是子串结尾,那么它不能被替换,所以是f[i-1]

    而如果它是子串结尾,它既可以不被替换,即f[i-1]

    也可以被替换,那么替换整个短串,转移的地方就是f[i-len]

    然后转移一下即可,建议从1开始读入字符串方便转移

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <cstring>
     4 #define N 100100
     5 #define mod 1000000007
     6 #define ui unsigned int
     7 #define ll long long
     8 using namespace std;
     9 
    10 int T,ls,lt;
    11 int ed[N],nxt[N];
    12 ui f[N];
    13 char s[N],t[N];
    14 void get_kmp()
    15 {
    16     int i=1,j=0;
    17     nxt[1]=0;
    18     while(i<=lt)
    19     {
    20         if(j==0||t[i]==t[j])
    21         {
    22             i++;
    23             j++;
    24             nxt[i]=j;
    25         }else{
    26             j=nxt[j];
    27         }
    28     }
    29 }
    30 void KMP()
    31 {
    32     int i=1,j=1;
    33     while(i<=ls)
    34     {
    35         if(j==0||s[i]==t[j])
    36         {
    37             i++;
    38             j++;
    39         }else{
    40             j=nxt[j];
    41         }
    42         if(j==lt+1)
    43         {
    44             ed[i-1]=1;
    45             j=nxt[j];
    46         }
    47     }
    48 }
    49 ui solve()
    50 {
    51     f[0]=1;
    52     for(int i=1;i<=ls;i++)
    53     {
    54         if(ed[i]==1)
    55         {
    56             f[i]=(f[i-lt]+f[i-1])%mod;
    57         }else{
    58             f[i]=f[i-1];
    59         }
    60     }
    61     return f[ls];
    62 }
    63 
    64 int main()
    65 {
    66     //freopen("aa.in","r",stdin);
    67     scanf("%d",&T);
    68     for(int i=1;i<=T;i++)
    69     {
    70         memset(nxt,0,sizeof(nxt));
    71         memset(ed,0,sizeof(ed));
    72         memset(f,0,sizeof(f));
    73         scanf("%s",s+1),ls=strlen(s+1);
    74         scanf("%s",t+1),lt=strlen(t+1);
    75         get_kmp();
    76         KMP();
    77         printf("Case #%d: %u\n",i,solve());
    78     }
    79     return 0;
    80 }
  • 相关阅读:
    POJ 2892 Tunnel Warfare(树状数组+二分)
    POJ 2886 Who Gets the Most Candies?(树状数组+二分)
    POJ 2492 A Bug's Life(并查集)
    POJ 1182 食物链(并查集)
    POJ 1703 Find them, Catch them(种类并查集)
    TC SRM 582 DIV 2
    函数
    shell进阶--流程
    计划任务 at,cron
    kill命令
  • 原文地址:https://www.cnblogs.com/guapisolo/p/9696928.html
Copyright © 2011-2022 走看看