C++進階-3-4stack容器、queue容器
阿新 • • 發佈:2022-05-07
題目連結
思考:剛開始想的時候想成了區間dp,思考相同長度下不同位置的字串的匹配,大概的想法是用\(dp[len][i][j]\)來表示長度為len的A串從i開始的子串變成B串從位置j開始所需要的最小代價,後面發現運算元有三種,很難用區間的方式來維護,畢竟修改完全可以不在兩端,而且複雜度也是在\(O(10^8)\)不可能接受,所以作罷。
正解:用\(dp[i][j]\)表示A從\([1...i]\)的子串變成B從\([1...j]\)所需要的最小代價,分析三種運算元
- 在A的末尾增加一個元素,此時代價為\(dp[i][j-1]+1\)
- 在B的末尾增加一個元素,此時代價為\(dp[i-1][j]+1\)
- 將A的末尾元素進行修改,如果不用修改,也就是\(A_i= B_j\)時,此時A的末尾元素不同進行修改得
初始狀態
\[ dp[i][j]= \begin{cases} dp[0][j]=j\\ dp[i][0]=i \end{cases} \]為什麼從左到右推進是可以的呢,首先我們可以想象一個位置\(A_i\)假設它應該匹配上的是一個後面的\(B_j\)
class Solution { public: int minDistance(string word1, string word2) { int n=word1.size(),m=word2.size(); int dp[n+1][m+1]; memset(dp,0,sizeof dp); for(int i=0;i<=n;i++) dp[i][0]=i; for(int j=0;j<=m;j++) dp[0][j]=j; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ int l=dp[i][j-1]+1; //這裡表示A+1 int r=dp[i-1][j]+1; //這裡表示B+1; int c=dp[i-1][j-1]+(word1[i-1]!=word2[j-1]); dp[i][j]=min(l,min(r,c)); } } return dp[n][m]; } };