子串
题目描述
有两个仅包含小写英文字母的字符串 AA 和 BB。
现在要从字符串 AA 中取出 kk 个互不重叠的非空子串,然后把这 kk 个子串按照其在字符串 AA 中出现的顺序依次连接起来得到一个新的字符串。请问有多少种方案可以使得这个新串与字符串 BB 相等?
注意:子串取出的位置不同也认为是不同的方案。
输入输出格式
输入格式:
第一行是三个正整数 n,m,kn,m,k,分别表示字符串 AA 的长度,字符串 BB 的长度,以及问题描述中所提到的 kk,每两个整数之间用一个空格隔开。
第二行包含一个长度为 nn 的字符串,表示字符串 AA。
第三行包含一个长度为 mm 的字符串,表示字符串 BB。
输出格式:
一个整数,表示所求方案数。
由于答案可能很大,所以这里要求输出答案对 10000000071000000007 取模的结果。
【题解】
有空补上,先上代码
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> #define ll long long #define mod 1000000007 #define num ch-'0' using namespace std; int n,m,k; ll f[201][201],sum[201][201]; char s1[10050],s2[10050]; void print(int x) { if(x<0){putchar('-');x=-x;} if(x>9) print(x/10); putchar(x%10+'0'); } void get(int &res) { char ch;bool flag=0; while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true); for(res=num;isdigit(ch=getchar());res=res*10+num); (flag)&&(res=-res); } int main() { get(n),get(m),get(k); scanf("%s%s",s1,s2); f[0][0]=1; for(int i=1;i<=n;i++) for(int j=m;j>=1;j--) for(int w=k;w>=1;w--) { if(s1[i-1]==s2[j-1]) { sum[j][w]=(sum[j-1][w]+f[j-1][w-1])%mod; f[j][w]=(f[j][w]+sum[j][w])%mod; } else sum[j][w]=0; } print(f[m][k]); return 0; }