P2758 編輯距離做題筆記
阿新 • • 發佈:2022-05-13
這題是昨天做的,寫到一半打模擬賽了,斷了網,沒有存,順帶吐槽洛谷部落格沒有草稿箱,再加上今天上午也有模擬賽,所以咕咕咕到了現在才來寫做題筆記。開始看題時一臉懵逼,可能是因為平時做 dp 題想太少且看題解太多的原因吧,經常想不出狀態轉移方程,只好看來題解,題解裡有兩種做法,一種遞迴,一種遞推,由於遞迴過於罕見,就選擇了自己比較熟悉的遞推,具體思路是用 \(s_{i,j}\) 表示 a 序列的 1 到 i 部分變成 b 序列的 1 到 j 部分至少需要幾次操作。狀態轉移方程: \(s_{i,j}\) 可以從 \(s_{i-1,j}\)、\(s_{i,j-1}\) 和 \(s_{i-1,j-1}\)
#include <bits/stdc++.h> using namespace std; char c[3005],d[3005]; int n,m,s[3005][3005],i,j; int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin>>c+1>>d+1; n=strlen(c+1); m=strlen(d+1); for (i=1;i<=n;i++) { s[i][0]=i; } for (i=1;i<=m;i++) { s[0][i]=i; } for (i=1;i<=n;i++) { for (j=1;j<=m;j++) { if (c[i]==d[j]) s[i][j]=s[i-1][j-1]; else s[i][j]=min(s[i-1][j-1],min(s[i][j-1],s[i-1][j]))+1; } } cout<<s[n][m]<<endl; return 0; }