题目描述
求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,k为结尾有多少个,那么它的贡献就是下一个a>=i,b>=j,c>=k的dp[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;
}