String Game---The 14th Jilin Provincial Collegiate Programming Contest

String Game---The 14th Jilin Provincial Collegiate Programming Contest

题意:

clair的字符串中有几种子序列等于bob的字符串

思路:

自前向后遍历clair的字符串( i=1;i<=l1;i++)
自后向前遍历bob的字符串( j=l2;j>=1;j–)
dp【j】代表clair前i个字符有dp【j】种子序列等于bob前j个字符

 if(c[i]==b[j])dp[j]=(dp[j-1]+dp[j])%mod;
 ///c的第i位作为b的第j位时,前j-1个字符的选择有dp【j-1】种方法

假如clair字符串:eeettt
bob字符串:ett
String Game---The 14th Jilin Provincial Collegiate Programming Contest
比如 i=4 的时候 (此时指向clair的第一个t)
把这个t当做ett中的第二个t(j=3) clair字符串前i-1位可以拼成et的种数为0(j=2) 那么clair前i位可以拼成ett的子序列的种数增加0

把这个t当做ett中的第一个t(j=2) clair字符串前i-1位可以拼成e的种数为3(j=1) 那么clair前i位可以拼成et的子序列的种数增加3

if(c[i]==b[j]),那么dp【j】就会增加,增加的方案数是以“clair的第i位作为bob的第j位”为前提
倘若对于bob字符串自前向后遍历,
若(c[i]==b[j-1]),dp【j-1】更新,(代表“clair的第i位作为bob的第j-1位),此时若(c[i]==b[j])也成立,那么dp【j】+=dp【j-1】,此时dp【j】的方案里包含了把“clair的第i位作为bob的第j-1位”的情况,与(c[i]==b[j])成立的条件:“把clair的第i位作为bob的第j位” 冲突,所以一定要是自后向前遍历

代码:

#include<algorithm>
#include<stdio.h>
#include<string>
#include<iostream>
#include<string.h>
using namespace std;
typedef long long ll;
char c[5007],b[1007];
const int mod=1e9+7;
int dp[1010];
int main()
{
    while(~scanf("%s",c+1))
    {
        scanf("%s",b+1);
        int l1=strlen(c+1),l2=strlen(b+1);
        //cout<<l1<<" "<<l2<<endl;
        memset(dp,0,sizeof(dp));
        dp[0]=1;
        for(int i=1;i<=l1;i++)
        {
            for(int j=l2;j>=1;j--)
            {
                if(c[i]==b[j])dp[j]=(dp[j-1]+dp[j])%mod;
                ///c的第i位作为b的第j位时,前j-1个字符的选择有dp【j-1】种方法
            }
            ///i只能同时与一个j匹配,则从后向前遍历
        }
        cout<<dp[l2]<<endl;
    }
    return 0;
}

上一篇:HZNU Training 22 for Zhejiang Provincial Competition 2020


下一篇:HZNU Training 5 for Zhejiang Provincial Competition 2020