FZU - 2024 LCS && EditStep
1553 ワード
タイトル:
a,bの2文字列,長さLen(1<=Len<=1000)を与え,これら2文字列のLCS長とEditStepをそれぞれ求める.次のようになります.
LCSは、2つの文字列の最長共通サブストリングです.
EditStepは、1文字を追加したり、1文字を削除したり、1文字を置き換えたりして、a列とb列を同じにするために必要な操作個数です.
考え方:LCSは言わないが、EditStepは:ans[i][j]がstr 1の前i、str 2の前jの最小ステップ数を表し、3つの場合、削除、追加、置換、削除と置換の効果は同じであり、str 1[i]=str 2[j]であればdp[i-1][j-1]となり、等しくなければ、置換すればこれに加えて+1となり、すべての場合の最小値をとる
a,bの2文字列,長さLen(1<=Len<=1000)を与え,これら2文字列のLCS長とEditStepをそれぞれ求める.次のようになります.
LCSは、2つの文字列の最長共通サブストリングです.
EditStepは、1文字を追加したり、1文字を削除したり、1文字を置き換えたりして、a列とb列を同じにするために必要な操作個数です.
考え方:LCSは言わないが、EditStepは:ans[i][j]がstr 1の前i、str 2の前jの最小ステップ数を表し、3つの場合、削除、追加、置換、削除と置換の効果は同じであり、str 1[i]=str 2[j]であればdp[i-1][j-1]となり、等しくなければ、置換すればこれに加えて+1となり、すべての場合の最小値をとる
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 1005;
char str1[MAXN],str2[MAXN];
int dp[MAXN][MAXN];
int ans[MAXN][MAXN];
int main(){
int t,cas=1;
scanf("%d%*c",&t);
while (t--){
scanf("%s%s",str1,str2);
memset(dp,0,sizeof(dp));
int len1 = strlen(str1),len2 = strlen(str2);
for (int i = 0; i <= len1; i++)
ans[i][0] = i;
for (int j = 0; j <= len2; j++)
ans[0][j] = j;
int t;
for (int i = 1; i <= len1; i++)
for (int j = 1; j <= len2; j++){
if (str1[i-1] == str2[j-1]){
dp[i][j] = dp[i-1][j-1] + 1;
t = 0;
}
else {
dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
t = 1;
}
ans[i][j] = min(ans[i-1][j-1]+t,min(ans[i-1][j]+1,ans[i][j-1]+1));
}
printf("Case %d: LCS=%d EditStep=%d
",cas++,dp[len1][len2],ans[len1][len2]);
}
return 0;
}