【codevs 1862】LCS問題+LCS的計數
阿新 • • 發佈:2019-01-30
LCS的模版
#include<bits/stdc++.h> using namespace std; int len1,len2; char a[5010],b[5010]; int dp[5010][5010]; int tot = 0; int main() { ios::sync_with_stdio(false); cin>>a+1>>b+1; len1 = strlen(a+1); len2 = strlen(b+1); len1--,len2--; for(int i=1;i<=len1;i++) { for(int j=1;j<=len2;j++) { if(a[i]==b[j]) { dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1); } else { dp[i][j] = max(dp[i-1][j],dp[i][j-1]); } } } cout<<dp[len1][len2]<<endl<<tot; return 0; }
然後這題還要統計LCS的個數。
參照一般的最長公共子序列的做法
if s1[i]==s2[j] then f[i][j]=f[i-1][j-1]+1
else f[i][j]=max(f[i][j-1],f[i-1][j])
然後我們用g[i][j]來表示方案數。
對於s1[i]==s2[i]
g[i][j]=g[i-1][j-1]+k1*g[i-1][j]+k2*g[i][j-1]
f[i][j]=f[i-1][j] then k1=1 else k1=0;
f[i][j]=f[i][j-1] then k2=1 else k2=0;
對於s1[i]!=s2[i]
g[i][j]=g[i-1][j-1]+k1*g[i-1][j]+k2*g[i][j-1]-k3*g[i-1][j-1]
f[i][j]=f[i-1][j] then k1=1 else k1=0;
f[i][j]=f[i][j-1] then k2=1 else k2=0;
f[i][j]=f[i-1][j-1] then k3=1 else k3=0;
#include <stdio.h> #include <string.h> #include<iostream> #define max(a,b) a>b?a:b using namespace std; const int MOD=100000000; int f[2][5001],g[2][5001]; char s1[5001],s2[5002]; int len1,len2; int main() { scanf("%s%s",s1,s2); len1=strlen(s1); len2=strlen(s2); for (int i=len1-1;i>=1;--i) s1[i]=s1[i-1]; for (int i=len2-1;i>=1;--i) s2[i]=s2[i-1]; len1--;len2--; int pre=0,now=1; for (int i=1;i<=len2;i++) g[0][i]=1; g[pre][0]=1; for (int i=1;i<=len1;++i) { for (int j=1;j<=len2;++j) f[now][j]=g[now][j]=0; g[now][0]=1; for (int j=1;j<=len2;++j) if(s1[i]==s2[j]) { f[now][j]=f[pre][j-1]+1; g[now][j]=g[pre][j-1],g[now][j]%=MOD; if (f[now][j]==f[pre][j]) g[now][j]+=g[pre][j],g[now][j]%=MOD; if (f[now][j]==f[now][j-1]) g[now][j]+=g[now][j-1],g[now][j]%=MOD; } else { f[now][j]=max(f[pre][j],f[now][j-1]); if (f[now][j]==f[pre][j]) g[now][j]+=g[pre][j],g[now][j]%=MOD; if (f[now][j]==f[now][j-1]) g[now][j]+=g[now][j-1],g[now][j]%=MOD; if (f[now][j]==f[pre][j-1]) g[now][j]-=g[pre][j-1],g[now][j]=(g[now][j]+MOD)%MOD; }//cout<<i<<" "<<j<<" "<<f[now][j]<<" "<<g[now][j]<<endl;} int t=pre;pre=now;now=t; } printf("%d\n%d\n",f[pre][len2],g[pre][len2]); return 0; }