第一个问题应该都是会的,主要分析第二问。
定义表示对应的状态长度等于的公共子序列的数量。
1.如果,则表示可以由推出。
2.如果,则表示可以由推出。
3.如果,则表示可以由推出。
4.如果,那么,即2、3都会满足,并且都包含,所以此时需要减去一个

还需要滚动数组。

Code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 7, mod = 1e8;
int f[2][5005];
ll g[2][5005];
char A[5005],B[5005];
int main() {
    scanf("%s%s",A+1,B+1);
    int n=strlen(A+1)-1,m=strlen(B+1)-1;
    for(int i = 1; i <= m; i++) g[0][i] = 1; g[0][0] = g[1][0] = 1;
    int cur(0);
    for(int i=1;i<=n;++i) {
        cur^=1;
        for(int j=1;j<=m;++j) {
            g[cur][j] = 0;
            if(A[i]==B[j]) {
                f[cur][j]=f[cur^1][j-1]+1;
                g[cur][j]=g[cur^1][j-1];
            }
            else {
                f[cur][j]=max(f[cur][j-1],f[cur^1][j]);
                if(f[cur][j]==f[cur^1][j-1])
                    g[cur][j]=mod-g[cur^1][j-1];
            }
            if(f[cur][j]==f[cur][j-1]) g[cur][j]+=g[cur][j-1];
            if(f[cur][j]==f[cur^1][j]) g[cur][j]+=g[cur^1][j];
            g[cur][j]%=mod;
        }
    }
    printf("%d\n",f[cur][m]);
    printf("%d\n",g[cur][m]);
    return 0;
}