码迷,mamicode.com
首页 > 其他好文 > 详细

2015提高组 子串

时间:2018-09-27 20:39:23      阅读:137      评论:0      收藏:0      [点我收藏+]

标签:scanf   sdi   tchar   bottom   转移   str   位置   lib   har   

题目描述

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

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

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

输入输出格式

输入格式:

 

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

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

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

 

输出格式:

 

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

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


lv神Day6T2,一个爆水的dp,呃,然而净顾着写T1,还忘了删注释

首先dp方程是好推的,dp[i][j][l][0]代表主串到i,模式串到j,分了l段,当前位可取也可不取

dp[i][j][l][1]代表主串到i,模式串到j,分了l段,当前位必须取

dp[i][j][l][1]=dp[i-1][j-1][l][1]+dp[i-1][j-1][l-1][0]

dp[i][j][l][0]=dp[i][j][l][1]+dp[i-1][j][l][0]

然后就发现MLE了,怎么解决呢?

我们将这个dp数组看做一个网格图

每一个dp[i][j][l][0],都是从他的左上角和他的上方的两个方格处转移过来的

所以我们将循环倒过来,这样就可以压缩我们的状态,提前计算出要处理的方格的上面的方格,再从前面的方格转移

如下:
dp[j][l][1]=dp[j-1][l][1]+dp[j-1][l-1][0]

dp[j][l][0]=dp[j][i][1]+dp[j-1][l][0]

然后就是基础操作

下面给出代码:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
inline int rd(){
    int x=0,f=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch==-) f=-1;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-0;
    return x*f;
}
inline void write(int x){
    if(x<0) putchar(-),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+0);
    return ;
}
int dp[1006][206][2];
char a[100006];
char b[100006];
int n,m,k;
int mod=1000000007;
int main(){
    n=rd();
    m=rd();
    k=rd();
    scanf("%s%s",a+1,b+1);
    dp[0][0][0]=1;
    for(int i=1;i<=n;i++){
        for(int j=m;j>=1;j--){
            if(a[i]==b[j]){
                for(int v=k;v>=1;v--){
                    dp[j][v][1]=(dp[j-1][v-1][0]+dp[j-1][v][1])%mod;
                    dp[j][v][0]=(dp[j][v][1]+dp[j][v][0])%mod;
                }
            }
            else for(int v=1;v<=k;v++) dp[j][v][1]=0;
        }
    }
    printf("%d",dp[m][k][0]);
    return 0;
}

 

2015提高组 子串

标签:scanf   sdi   tchar   bottom   转移   str   位置   lib   har   

原文地址:https://www.cnblogs.com/WWHHTT/p/9715303.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!