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 }
  • 相关阅读:
    PAT 1006 Sign In and Sign Out
    PAT 1004. Counting Leaves
    JavaEE开发环境安装
    NoSql数据库探讨
    maven的配置
    VMWARE 下使用 32位 Ubuntu Linux ,不能给它分配超过3.5G 内存?
    XCODE 4.3 WITH NO GCC?
    在苹果虚拟机上跑 ROR —— Ruby on Rails On Vmware OSX 10.7.3
    推荐一首让人疯狂的好歌《Pumped Up Kicks》。好吧,顺便测下博客园可以写点无关技术的帖子吗?
    RUBY元编程学习之”编写你的第一种领域专属语言“
  • 原文地址:https://www.cnblogs.com/guapisolo/p/9696928.html
Copyright © 2011-2022 走看看