Codevs 4560 NOIP2015 D2T2 子串

来源:互联网 发布:各种排序算法比较 编辑:程序博客网 时间:2024/06/05 11:03
> 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 201using 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;}
0 0
原创粉丝点击