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 }
  • 相关阅读:
    tasker支持的shell 命令大全
    crx 文件安装 如何安装 Chrome插件
    python mac地址计算
    Java线程池
    springMVC请求过程
    java中特殊的String类型
    单例模式和多例模式
    hash算法学习
    arraylist和linkedlist的简单比较
    乐观锁和悲观锁
  • 原文地址:https://www.cnblogs.com/sin-mo/p/7191837.html
Copyright © 2011-2022 走看看