zoukankan      html  css  js  c++  java
  • Noip 2015 senior 复赛 Day2 子串

    Noip 2015 senior 复赛 Day2 T2

    【问题描述】

    有两个仅包含小写英文字母的字符串 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类型的题目,状态转移方程还是比较好推的:

           如果两个串的字符不同:

           Element_program[k][i][j] = (Element_program[k][i-1][j-1] + Ultimate_program[k-1][i-1][j-1]) % mod;

           对于每一次的字符比较:

    Ultimate_program[k][i][j] = (Ultimate_program[k][i-1][j] + Element_program[k][i][j]) % mod;

    但是这样推出来的状态转移方程由于3维,所以空间是会爆掉的,只能保证前7个点(记得需要把数组开小点)。那么解决方法是什么呢,可以直接降维,只要你这方面比较强。还可以使用动态数组。

    什么是动态数组呢?记得曾经一道求解二项式系数的题目吗?我们在求解的时候对于组合数是采用的杨辉三角,但是,数组是开不了n那么大的,所以我们采用只保存两层的方式。那么动态数组就是这样的思想,我们由于求解的问题只与n与n-1相关,所以我们也只保存这两层的数据,这样我们就能把3维降成两个2维的数组(也可以开dp[3][n][m])。

      

     1 #include<cstdio> //三维
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 #define N 1010
     8 #define M 205
     9 #define mod 1000000007 
    10 
    11 char first[N],second[M];
    12 int n,m,part;
    13 int Ultimate_program[M][N][M],Element_program[M][N][M];
    14 
    15 inline void ltsinit()
    16 {
    17     scanf("%d %d %d",&n,&m,&part);
    18     scanf("%s",first);
    19     scanf("%s",second);
    20 }
    21 
    22 inline void Dynamic_programming()
    23 {
    24     Ultimate_program[0][0][0] = 1;
    25     for(int i=1;i<=n;i++)
    26     {
    27         Ultimate_program[0][i][0] = 1;
    28         for(int j=1;j<=m;j++)
    29         {
    30             for(int k=1;k<=part;k++)
    31             {
    32                 if(first[i-1] != second[j-1])
    33                     Element_program[k][i][j] = 0;
    34                 else
    35                     Element_program[k][i][j] = (Element_program[k][i-1][j-1] + Ultimate_program[k-1][i-1][j-1]) % mod;
    36                 
    37                 Ultimate_program[k][i][j] = (Ultimate_program[k][i-1][j] + Element_program[k][i][j]) % mod;
    38             }
    39         }
    40     }
    41 }
    42 
    43 int main()
    44 {
    45 //    freopen("substring.in","r",stdin);
    46 //    freopen("substring.out","w",stdout);
    47     
    48     ltsinit();
    49     Dynamic_programming();
    50     printf("%d",Ultimate_program[part][n][m]);
    51     
    52     return 0;
    53 }
     1 #include<cstdio> //二维
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 #define N 1010
     8 #define M 205
     9 #define mod 1000000007 
    10 
    11 char first[N],second[M];
    12 int n,m,part;
    13 int Ultimate_program[M][M],Element_program[M][M];
    14 
    15 inline void ltsinit()
    16 {
    17     scanf("%d %d %d",&n,&m,&part);
    18     scanf("%s",first);
    19     scanf("%s",second);
    20 }
    21 
    22 inline void Dynamic_programming()
    23 {
    24     Ultimate_program[0][0] = 1;
    25     for(int i=1;i<=n;i++)
    26     {
    27 //        Ultimate_program[0][0] = 1;
    28         for(int j=m;j>=1;j--)
    29         {
    30             for(int k=min(part,j);k>=1;k--)
    31             {
    32                 if(first[i-1] != second[j-1])
    33                     Element_program[k][j] = 0;
    34                 else
    35                 {
    36                     Element_program[k][j] = (Ultimate_program[k-1][j-1] + Element_program[k][j-1]) % mod;
    37                     Ultimate_program[k][j] = (Ultimate_program[k][j] + Element_program[k][j]) % mod;
    38                 }
    39             }
    40         }
    41     }
    42 }
    43 
    44 int main()
    45 {
    46 //    freopen("substring.in","r",stdin);
    47 //    freopen("substring.out","w",stdout);
    48     
    49     ltsinit();
    50     Dynamic_programming();
    51     printf("%d",Ultimate_program[part][m]);
    52     
    53     return 0;
    54 }
  • 相关阅读:
    [APM] OneAPM 云监控部署与试用体验
    Elastic Stack 安装
    xBIM 综合使用案例与 ASP.NET MVC 集成(一)
    JQuery DataTables Selected Row
    力导向图Demo
    WPF ViewModelLocator
    Syncfusion SfDataGrid 导出Excel
    HTML Table to Json
    .net core 2.0 虚拟目录下载 Android Apk 等文件
    在BootStrap的modal中使用Select2
  • 原文地址:https://www.cnblogs.com/sin-mo/p/7191837.html
Copyright © 2011-2022 走看看