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

简单线性dp

时间:2018-08-18 13:12:12      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:space   while   return   匹配   来源   scanf   mtu   位置   set   

  小zc现在有三个字符串,他想知道前两个字符串能不能生成第三个字符串,生成规则如下:第一个串的每个字符都可以往第二个串的任意位置插入(包括首尾位置),但必须保证来源于第一个串中的字符在生成后的串中的相对顺序不可以改变。

举个例子:
        String A: cu
        String B: mt
    那么,A和B可以生成的所有字符串是{cumt,cmut,cmtu,mcut,mctu,mtcu},而不能生成ucmt,因为uc来源于A串,但改变了A中字符原来的相对顺序。
    但小zc觉得这个问题太简单,于是他想让你计算对于给定的A, B, C串,共有多少种方案能够生成C串。方便起见,你只需要输出最后答案对1000000007取模的值。

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#define rep(i,l,r)  for (int i=l; i<=r; i++)
typedef long long ll;
using namespace std;
const int mod = 1e9+7;
const int N = 3000;
int l1,l2,l3,dp[N][N]; 
//dp[i][j]表示已经匹配了s1前i个字符,s2前j个字符的方案数
char s1[N],s2[N],s3[N*2];
 
void solve() {
    memset(dp,0,sizeof(dp));
    dp[0][0] =1;
    rep(i,1,l1) {
        if(s1[i] == s3[i]) 
            dp[i][0] = dp[i-1][0];
    }
    rep(i,1,l2) {
        if(s2[i] == s3[i]) 
            dp[0][i] = dp[0][i-1];
    }
 
    rep(i,1,l1) {
        rep(j,1,l2) {
            if(s1[i] == s3[i+j]) {
                dp[i][j] = (dp[i][j] + dp[i-1][j]) %mod;
            }
            if(s2[j] == s3[i+j]) {
                dp[i][j] = (dp[i][j] + dp[i][j-1]) %mod;
            }           
        }
    }
    cout << dp[l1][l2] <<endl; 
}
 
int main(){
    int T; scanf("%d",&T);
    while (T--) {
        scanf("%s %s %s",s1+1,s2+1,s3+1);
        l1 = strlen(s1+1);
        l2 = strlen(s2+1);
        l3 = strlen(s3+1);
        solve();
    }
    return 0;
}

 

简单线性dp

标签:space   while   return   匹配   来源   scanf   mtu   位置   set   

原文地址:https://www.cnblogs.com/Draymonder/p/9496612.html

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