子串

题目描述

有两个仅包含小写英文字母的字符串 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;
}
原文地址:https://www.cnblogs.com/mxrmxr/p/9715190.html