zoukankan      html  css  js  c++  java
  • [luogu2679] 子串 (多维dp)

    传送门

    Description

    有两个仅包含小写英文字母的字符串 A 和 B 。

    现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一个新的字符串。请问有多少种方案可以使得这个新串与字符串 B 相等?

    注意:子串取出的位置不同也认为是不同的方案。

    Input

    第一行是三个正整数 n,m,k,分别表示字符串 A 的长度,字符串 B 的长度,以及问题描述中所提到的 k ,每两个整数之间用一个空格隔开。

    第二行包含一个长度为 n 的字符串,表示字符串 A 。

    第三行包含一个长度为 m 的字符串,表示字符串 B 。

    Output

    一个整数,表示所求方案数。

    由于答案可能很大,所以这里要求输出答案对 1000000007 取模的结果。

    Sample Input

    输入样例#1:
    6 3 1
    aabaab
    aab

    输入样例#2:
    6 3 2
    aabaab
    aab

    输入样例#3:
    6 3 3
    aabaab
    aab

    Sample Ouput

    输出样例#1:
    2

    输出样例#2:
    7

    输出样例#3:
    7

    HINT

    Solution

    (f[i][j][k]) A第i个B第j个第k个子串的答案
    (g[i][j][k]) A第i个B第j个第k个子串A[i]必选答案

    Code

    //By Menteur_Hxy
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define F(i,a,b) for(register int i=(a);i<=(b);i++)
    using namespace std;
    
    const int MOD=1000000007;
    const int N=1010,M=210;
    int n,m,K,fl;
    int f[2][N][M],g[2][N][M];
    char a[N],b[M];
    
    int main() {
    	scanf("%d%d%d%s%s",&n,&m,&K,a+1,b+1);
    	f[0][0][0]=1;
    	F(i,1,n) {
    		f[fl=i&1][0][0]=1;
    		F(j,1,m) F(k,1,K) 
    			g[fl][j][k]=(a[i]==b[j]?f[fl^1][j-1][k-1]+g[fl^1][j-1][k]:0)%MOD,
    			f[fl][j][k]=(f[fl^1][j][k]+g[fl][j][k])%MOD;
    	}
    	printf("%d",f[n&1][m][K]);
    	return 0;
    }
    
    版权声明:本文为博主原创文章,未经博主允许不得转载。 博主:https://www.cnblogs.com/Menteur-Hxy/
  • 相关阅读:
    cookie操作
    css加载动画...
    三目运算符的运用
    遍历对象长度
    2年
    相亲

    股市周期
    功利心
    思考笔记
  • 原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9402464.html
Copyright © 2011-2022 走看看