• 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 }
  • 相关阅读:
    剑指 Offer 22. 链表中倒数第k个节点(简单)
    剑指 Offer 18. 删除链表的节点(简单)
    Proxy error: Could not proxy request
    剑指 Offer 63. 股票的最大利润(中等)
    剑指 Offer 47. 礼物的最大价值(中等)
    剑指 Offer 42. 连续子数组的最大和(简单)
    oracle 常用函数之 字符函数
    oracle 常用函数之 日期函数
    oracle 常用函数之聚合函数
    jdbc
  • 原文地址:https://www.cnblogs.com/guapisolo/p/9696928.html
Copyright © 2020-2023  润新知