• 简单线性dp


      小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;
    }
  • 相关阅读:
    第01组 Beta冲刺(4-5)
    第01组 Beta冲刺(3-5)
    第01组 Beta冲刺(2-5)
    第01组 Beta冲刺(1-5)
    等价类划分-一个程序输入三个整数,判断三角形是不等边,还是等腰还是等边
    Jmeter入门(8)- Jmeter关联
    Jmeter发送数据库请求(JDBC Request)报错
    Jmeter入门(7)- 连接数据库
    Jmeter入门(6)- 参数化
    Jmeter入门(5)- jmeter取样器的HTTP请求
  • 原文地址:https://www.cnblogs.com/Draymonder/p/9496612.html
Copyright © 2020-2023  润新知