• Codevs 4560 NOIP2015 D2T2 子串


    > 4560 NOIP2015 D2T2 子串
     时间限制: 1 s
     空间限制: 128000 KB
     题目等级:黄金 Gold
    题目描述 Description
    有两个仅包含小写英文字母的字符串A和B。现在要从字符串A中取出k个互不重叠的非空子串,然后把这k个子串按照其在字符串A中出现的顺序依次连接起来得到一个新的字符串,请问有多少种方案可以使得这个新串与字符串B相等?注意:子串取出的位置不同也认为是不同的方案。
    输入描述 Input Description
    第一行是三个正整数n,m,k,分别表示字符串A的长度,字符串B的长度,以及问题描述中所提到的k,每两个整数之间用一个空格隔开。 
    第二行包含一个长度为n的字符串,表示字符串A。 第三行包含一个长度为m的字符串,表示字符串B。
    输出描述 Output Description
    输出共一行,包含一个整数,表示所求方案数。由于答案可能很大,所以这里要求输出答案对1,000,000,007取模的结果。
    样例输入 Sample Input
    【Input1】
    6 3 1 
    aabaab 
    aab
    【Input2】
    6 3 2 
    aabaab 
    aab
    【Input3】
    6 3 3 
    aabaab 
    aab
    样例输出 Sample Output
    【Output1】
    2
    【Output2】
    7
    【Output3】
    7
    数据范围及提示 Data Size & Hint
    对于第1组数据:1≤n≤5001≤m≤50,k=1; 
    对于第2组至第3组数据:1≤n≤5001≤m≤50,k=2; 
    对于第4组至第5组数据:1≤n≤5001≤m≤50,k=m; 
    对于第1组至第7组数据:1≤n≤5001≤m≤501≤k≤m; 
    对于第1组至第9组数据:1≤n≤10001≤m≤1001≤k≤m; 
    对于所有10组数据:1≤n≤10001≤m≤2001≤k≤m。
    /*
    方案数DP+滚动数组优化.
    f[i][j][p][]表示A串前i个字符B串前j个字符组成k个贡献的方案数.
    (最后一维对当前字符用不用讨论). 
    当前考虑两种状态:两个字符相等.
                     两个字符不等.
    关于取模的问题相关:(a+b+c)%p=((a+b)%p+c)%p.
    */
    #include<iostream>
    #include<cstdio>
    #define mod 1000000007
    #define MAXN 1001
    #define MAXM 201
    using namespace std;
    int f[2][MAXM][MAXM][2],n,m,k;
    char s1[MAXN],s2[MAXM];
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    int main()
    {
        n=read();m=read();k=read();
        for(int i=1;i<=n;i++)  cin>>s1[i];
        for(int i=1;i<=m;i++)  cin>>s2[i];
        f[0][0][0][0]=f[1][0][0][0]=1;
        for(int i=1;i<=n;i++)
          for(int j=1;j<=min(i,m);j++)
            for(int p=1;p<=k;p++){
                int now=i&1,last=(i-1)&1;
                if(s1[i]==s2[j]) f[now][j][p][1]=((f[last][j-1][p][1]+f[last][j-1][p-1][0])%mod
                                 +f[last][j-1][p-1][1])%mod,
                                 f[now][j][p][0]=(f[last][j][p][0]+f[last][j][p][1])%mod;
                else f[now][j][p][1]=0,f[now][j][p][0]=(f[last][j][p][0]+f[last][j][p][1])%mod;; 
            }
        printf("%d",(f[n&1][m][k][0]%mod+f[n&1][m][k][1]%mod)%mod);
        return 0;
    }
  • 相关阅读:
    Linux利器strace
    记一次MongoDB性能问题
    mongodb慢查询记录
    PHP操作MongoDB学习笔记
    字典NSDictionary的常见用法
    字典与自定义对象的相互转换
    URLString中文字符转义
    常见序列化与反序列化方法
    Swift处理异常的三种方式-try
    客户端Socket使用步骤
  • 原文地址:https://www.cnblogs.com/nancheng58/p/6070802.html
Copyright © 2020-2023  润新知