2015年 day2.2子串

子串
 
 
 题目描述
有两个仅包含小写英文字母的字符串 A 和 B。现在要从字符串 A 中取出 k 个互不重
叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一 个新的字符串,请问有多少种方案可以使得这个新串与字符串 B 相等?注意:子串取出 的位置不同也认为是不同的方案。
 
输入格式:
第一行是三个正整数 n,m,k,分别表示字符串 A 的长度,字符串 B 的长度,以及问
题描述中所提到的 k,每两个整数之间用一个空格隔开。 第二行包含一个长度为 n 的字符串,表示字符串 A。 第三行包含一个长度为 m 的字符串,表示字符串 B。

输出格式:
输出共一行,包含一个整数,表示所求方案数。由于答案可能很大,所以这里要求输出答案对 1,000,000,007 取模的结果。
 
样例测试点#1
输入样例:

6 3 1
aabaab
aab

 

输出样例:
2
 
样例测试点#2
输入样例:

6 3 2
aabaab
aab

输出样例:
7
 
样例测试点#3
输入样例: 

6 3 3
aabaab
aab

输出样例:
7
 
//动态转移方程
//if(a[i]==b[j]){
//                  g[i][j][k]=(f[i-1][j-1][p-1]+g[i-1][j-1][q])%1000000007;
//                  f[i][j][k]=(f[i-1][j][k]+g[i][j][k])%1000000007;
//              }
//              else{
//                      g[i][j][k]=0;
//                      f[i][j][k]=f[i-1][j][k];
//                  }
//a[i]为a中第i个字符,b[j]为b中第j个字符,k是将b中前j个字符分成k份
//(从a中取出k个等于将b分成k份);
//当a[i]==b[j]时,①第i个不取有f[i-1][j][k]中情况;
//                ②第i个取且作为第k个部分共有
//                 f[i-1][j-1][k-1]+f[i-2][j-2][k-1]+f[i-3][j-3][k-1]+...+f[i-k+1][j-k+1][k-1];
//当a[i]!=b[j]时,f[i][j][k]=f[i-1][j][k];(a[i-1]与b[j]相对时的方案数); 
//要用滚动数组,f[][][]可以压缩到二维; 
#include<cstdio>
int n,m,k,g[2][202][202],f[202][202];
char a[1005],b[202];
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    scanf("%s",a+1);
    scanf("%s",b+1);
    f[0][0]=1;
    for(int i=1;i<=n;i++)
        for(int j=m;j>0;j--)
          for(int q=1;q<=j;q++){
              if(a[i]==b[j]){
                  g[i%2][j][q]=f[j-1][q-1]+g[(i-1)%2][j-1][q];
                  f[j][q]=f[j][q]+g[i%2][j][q];
              }
              else{
                  g[i%2][j][q]=0;
                  f[j][q]=f[j][q];
              }
              int x=0;
          }
    printf("%d",f[m][k]);
    return 0;
}
View Code

 

posted @ 2016-03-19 09:54  qg1  阅读(266)  评论(0编辑  收藏  举报