洛谷-1819 公共子序列_NOI导刊2011提高(03)

该博客介绍了如何求解三个字符序列的不同公共子序列数量,详细阐述了输入输出格式,并提供了样例及解题思路。针对30%的数据,序列长度不超过10;70%的数据,不超过50;而所有数据中,长度上限为150。样例给出了5个公共子序列:a, ab, aa, bb, b。" 123589583,1512397,欧盟与英国调查Google和Meta的'Jedi Blue'反垄断协议,"['网络', '广告技术', '反垄断法', '科技巨头']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述
求3个字符序列有多少个不同的公共子序列,不包括空序列。
输入输出格式
输入格式:
第一行为一个正整数N,表示3个序列的长度。
接下来3行,每行一个无空格长度为N的字符序列。只包含小写字母a到z。
输出格式:
一行一个正整数ANS。

输入输出样例
输入样例#1:
4
aabb
abab
baba

输出样例#1:
5

说明
对于30%的数据,N≤l0;
对于70%的数据,N≤50;对于100%的数据,N≤150。
【注意事项】
5种子序列是a,ab,aa,bb,b。

解释:dp[i][j][k]:以i,j,k为结尾有多少个,那么它的贡献就是下一个a>=i,b>=j,c>=k的dp[a][b][c],dp[i][j][k]:以i,j,k为结尾有多少个,那么它的贡献就是下一个a>=i,b>=j,c>=k的dp[a][b][c],dp[i][j][k]:i,j,ka>=i,b>=j,c>=kdp[a][b][c],因为只需要计数一次,取最近一个就好了

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<string>
#define int long long
using namespace std;
const int N=155;
const int mod=100000000;
int n,A[N][26],B[N][26],C[N][26],dp[N][N][N];
char a[N],b[N],c[N];
main (){
    scanf ("%lld",&n);
    scanf ("%s%s%s",a+1,b+1,c+1);
    for (int i=0;i<26;++i)
        A[n][i]=B[n][i]=C[n][i]=n+1;
    for (int i=n-1;i>=0;--i){
        memcpy(A[i],A[i+1],sizeof(A[i]));
        memcpy(B[i],B[i+1],sizeof(B[i]));
        memcpy(C[i],C[i+1],sizeof(C[i]));
        A[i][a[i+1]-'a']=i+1;
        B[i][b[i+1]-'a']=i+1;
        C[i][c[i+1]-'a']=i+1;
    }
    dp[0][0][0]=1;
    for (int i=0;i<=n;++i)
        for (int j=0;j<=n;++j)
            for (int k=0;k<=n;++k)
                for (int p=0;dp[i][j][k] && p<26;++p)
                    (dp[A[i][p]][B[j][p]][C[k][p]]+=dp[i][j][k])%=mod;
    int ans=0;
    for (int i=1;i<=n;++i)
        for (int j=1;j<=n;++j)
            for (int k=1;k<=n;++k)
                (ans+=dp[i][j][k])%=mod;
    printf ("%lld\n",ans);
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值