2つの文字列の最長共通部分列の数を検索し、\(N- \のLeq 5000 \)
解決
最初の質問、考える\(F [i]の[jは ] \) 2つの文字列が走った表し\(I、J \)最長共通部分列の位置、そして
\ [F [i]は[J ] = \ MAX(F [I-1]〜
[J]、F [i]は[J-1]、F [I-1] [J-1] + [S [i]は== T [J])\] 暴力への転送
2番目の質問、考える\(G [i]の[jを ] \) 2つの文字列を表して走った\(I、J \)最長共通サブシーケンスプログラム位置の数、通常からの最初の統計\(F [ ] [J]、F [I I-1]〜[J-1] \) プログラムの数を超えると、2つの特殊なケースを考慮
- もし\(F [I] [J ] = F [I-1] [J-1] \) と\(S [I] \ NEQ T [J] \)追加の減算のため、次に必要\(G [I -1] [J-1] \ )
- 場合\(F [I] [J ] = F [I-1] [J-1] +1 \) と\(S [I] = T [J] \)、次いで必要が追加追加する\(Gを[ I-1] [J-1 ] \)
#include <bits/stdc++.h>
using namespace std;
const int mod = 100000000;
int n,m,f[2][5005],g[2][5005];
char s[5005],t[5005];
signed main() {
cin>>s+1>>t+1;
n=strlen(s+1);
m=strlen(t+1);
--n; --m;
for(int i=0;i<=n;i++) g[0][i]=1;
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) g[i&1][j]=0;
g[i&1][0]=1;
for(int j=1;j<=m;j++) {
f[i&1][j]=max(max(f[i-1&1][j],f[i&1][j-1]),
f[i-1&1][j-1]+(s[i]==t[j]));
if(f[i&1][j]==f[i-1&1][j]) (g[i&1][j]+=g[i-1&1][j])%=mod;
if(f[i&1][j]==f[i&1][j-1]) (g[i&1][j]+=g[i&1][j-1])%=mod;
if(f[i&1][j]==f[i-1&1][j-1]&&s[i]!=t[j])
(g[i&1][j]+=mod-g[i-1&1][j-1])%=mod;
if(f[i&1][j]==f[i-1&1][j-1]+1&&s[i]==t[j])
(g[i&1][j]+=g[i-1&1][j-1])%=mod;
}
}
cout<<f[n&1][m]<<"\n"<<g[n&1][m]<<endl;
}