Vijos[1982]NOIP2015Day2T2 子串 substring 动态规划

子串 (substring.cpp/c/pas)   题目链接

【问题描述】
有两个仅包含小写英文字母的字符串 A 和 B。现在要从字符串 A 中取出 k 个 互不重叠 的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一
个新的字符串,请问有多少种方案可以使得这个新串与字符串 B 相等?注意:子串取出的位置不同也认为是不同的方案 。
【输入格式】
输入文件名为 substring.in。
第一行是三个正整数 n,m,k,分别表示字符串 A 的长度,字符串 B 的长度,以及问题描述中所提到的 k,每两个整数之间用一个空格隔开。
第二行包含一个长度为 n 的字符串,表示字符串 A。
第三行包含一个长度为 m 的字符串,表示字符串 B。
【输出格式】
输出文件名为 substring.out。
输出共一行,包含一个整数,表示所求方案数。 由于答案可能很大,所以这里要求对输出答案对 1,000,000,007 取模 的结果。
【输入输出样例 1】
substring.in
6 3 1
aabaab
aab
substring.out
2
【输入输出样例 2】
substring.in
6 3 2
aabaab
aab
substring.out
7
【输入输出样例 3】
substring.in
6 3 3
aabaab
aab
substring.out
7

【题解】
NOIP2015Day2T2
一道好好的DP题
我们用dp[i][j][k]表示在B串中匹配i个,在A串中匹配到的位置为j,共使用k个子串的方案总数,则dp[i][j][k]=Σdp[i-1][j‘][k-1] +dp[i-1][j-1][k]
那么,对于Σ可以用前缀和优化,这样的时间就可以卡进去了,但是空间还是要炸,所以我们采用滚动数组来优化空间即可。详见代码。

#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
const int N=1000+5,M=200+5;
const int mod=1e9+7;
char s1[N],s2[M];
int n,m,K;
int dp[2][N][M],sum[2][N][M];
//dp[i][j][k]=Σdp[i-1][j‘][k-1](1<=j‘<=j-1) +dp[i-1][j-1][k]
int main(){
    scanf("%d%d%d%s%s",&n,&m,&K,s1+1,s2+1);
    memset(dp,0,sizeof dp);
    memset(sum,0,sizeof sum);
    int I=0,J=1;
    for (int i=1;i<=n;i++){
        if (s2[1]==s1[i])
            dp[0][i][1]=1;
        sum[0][i][1]=sum[0][i-1][1]+dp[0][i][1];
    }
    for (int i=2;i<=m;i++,I^=1,J^=1){
        memset(dp[J],0,sizeof dp[J]);
        memset(sum[J],0,sizeof sum[J]);
        for (int j=1;j<=n;j++){
            if (s2[i]!=s1[j])
                continue;
            for (int k=1;k<=K;k++)
                if (j>=2)
                    dp[J][j][k]=(sum[I][j-1][k-1]+dp[I][j-1][k])%mod;
                else
                    dp[J][j][k]=dp[I][j-1][k];
        }
        for (int k=1;k<=K;k++)
            for (int j=1;j<=n;j++)
                sum[J][j][k]=(sum[J][j-1][k]+dp[J][j][k])%mod;
    }
    printf("%d",sum[I][n][K]);
    return 0;
}
时间: 2024-10-13 08:12:03

Vijos[1982]NOIP2015Day2T2 子串 substring 动态规划的相关文章

求两个字符串最长公共子串(动态规划)

code如下: //Longest common sequence, dynamic programming method void FindLCS(char *str1, char *str2) { if(str1 == NULL || str2 == NULL) return; int length1 = strlen(str1)+1; int length2 = strlen(str2)+1; int **csLength,**direction;//two arrays to recor

[LeetCode] 647. 回文子串 ☆☆☆(最长子串、动态规划、中心扩展算法)

描述 给定一个字符串,你的任务是计算这个字符串中有多少个回文子串. 具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被计为是不同的子串. 示例 1: 输入: "abc"输出: 3解释: 三个回文子串: "a", "b", "c".示例 2: 输入: "aaa"输出: 6说明: 6个回文子串: "a", "a", "a", "

vijos 1982 子串

感谢http://blog.csdn.net/gengmingrui/article/details/49849023 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 1050 #define maxm 250 #define mod 1000000007 using namespace std; int n,m,l,f[2][max

[NOIP2015] 子串substring 题解

[题目描述] 有两个仅包含小写英文字母的字符串A和B.现在要从字符串A中取出k个互不重叠的非空子串,然后把这k个子串按照其在字符串A中出现的顺序依次连接起来得到一个新的字符串,请问有多少种方案可以使得这个新串与字符串B相等?注意:子串取出的位置不同也认为是不同的方案. 由于答案可能很大,所以这里要求输出答案对1,000,000,007取模的结果. [样例输入1] 6 3 1 aabaab aab [样例输出1] 2 [样例输入2] 6 3 2 aabaab aab [样例输出2] 7 [样例输入

最大子串和--动态规划经典问题

[问题描述] 在长度为N的整形数组中,求连续子串的和的最大值,要求复杂度为O(N). 例如:1 2 3 -1 -20 100 34,结果为134. #include<stdio.h> #include<iostream> #include<math.h> #include<stdlib.h> #include<ctype.h> #include<algorithm> #include<vector> #include<

NOIP2015Day2T2子串(字符串dp)

又被"if(a=b)"坑了QAQ...写C++还是得开Warning,这么久了pascal还没改过来咋回事啊QWQ 题目大意就不说了OWO 网上的题解都不怎么看得懂啊...好像写得都很乱?还是我太sb了 f[i][j][k][0]表示A串前i个字符和B串前j个字符能够匹配,并且分成k段,a[i]不选.f[i][j][k][1]同理但a[i]要选. 于是...f[i][j][k][0]=f[i-1][j][k][1]+f[i-1][j][k][0]; if(a[i]==b[j])f[i]

LeetCode-5:Longest Palindromic Substring(最长回文子字符串)

描述:给一个字符串s,查找它的最长的回文子串.s的长度不超过1000. Input: "babad" Output: "bab" Note: "aba" is also a valid answer. 我是采用动态规划解决此题的.官方的solutions中提供了几种思路,包括我使用的DP.这里摘要如下: 思路1: 将s反转得到s',然后查找s和s'的最长公共子串substring,那么substring就是最长回文子串.比如:s = "

LeetCode 5 Longest Palindromic Substring(最长子序列)

题目来源:https://leetcode.com/problems/longest-palindromic-substring/ Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. 动态规划,类似于l

LeetCode:Longest Palindromic Substring

Longest Palindromic Substring Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. 动态规划解法 T(n) = O(n^2)  ,S(n) = O(n^2); Solutio