• NOIP2015 子串 (DP+优化)


    子串
    (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 取模的结果。

    【思路】

           DP+优化

           设f[k][i][j]为已经有k段,A串匹配到i,B匹配到j的方案数,则有转移式:

                  f[k][i][j]=sigma{f[k-1][l][j-1]},A[i]==B[j]&&A[i-1]!=B[j-1]

                            = sigma{f[k-1][l][j-1]}+f[k][i-1][j-1],A[i]==B[j]&&A[i-1]==B[j-1]

           前缀和优化时间,滚动数组优化空间。

    【代码】

     1 #include<cstdio>
     2 #include<cstring>
     3 using namespace std;
     4 
     5 const int N = 1e3+5;
     6 const int M = 200+5;
     7 const int MOD = 1e9+7;
     8 
     9 int f[2][N][M],sum[2][N][M],n,m,K;
    10 char s1[N],s2[M];
    11 
    12 int main() {
    13     scanf("%d%d%d",&n,&m,&K);
    14     scanf("%s",s1+1),scanf("%s",s2+1);
    15     f[0][0][0]=1;
    16     for(int i=0;i<=n;i++) sum[0][i][0]=1;
    17     int x=0;
    18     for(int k=1;k<=K;k++) {
    19         x^=1;
    20         memset(sum[x],0,sizeof(sum[x]));
    21         memset(f[x],0,sizeof(f[x]));
    22         for(int i=1;i<=n;i++)
    23             for(int j=1;j<=m;j++) {
    24                 if(s1[i]==s2[j]) {
    25                     f[x][i][j]=sum[x^1][i-1][j-1];
    26                     if(s1[i-1]==s2[j-1]) f[x][i][j]=(f[x][i][j]+f[x][i-1][j-1])%MOD;
    27                 }
    28                 sum[x][i][j]=((sum[x][i][j]+sum[x][i-1][j])%MOD+f[x][i][j])%MOD;
    29             }
    30     }
    31     int ans=0;
    32     for(int i=1;i<=n;i++)
    33         ans=(ans+f[x][i][m])%MOD;
    34     printf("%d",ans);
    35     return 0;
    36 }
  • 相关阅读:
    php获取真实ip地址原理及实现
    关于DateTime计算某个日期过后的多少天之后的日期
    关于get_include_path()和set_include_path()的问题
    LinQ In Action 学习第三章
    LinQ In Action 学习第二章
    LinQ in Action 学习第一章 例子。
    asp.net create windows application and setup service.
    JS alert()、confirm()、prompt()的区别
    php获取用户 地区 、ip地址
    购物车相关 js
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5215282.html
Copyright © 2020-2023  润新知