1. 程式人生 > 其它 >編輯距離(洛谷p1279)

編輯距離(洛谷p1279)

https://www.luogu.com.cn/problem/P2758
這是一道特別惡劣的題,題面完全就是在誤導。
首先我們會發現這個題一共有三種操作方式,於是乎第一反應就會是想到貪心,結果就發現根本就想不到怎麼貪or幾乎所有貪心策略都很好找hack資料。
因此就可以斷定,這題還不如寫個dp。
根據一般的套路,為了避免在寫dp式的時候再次陷入貪心的思維陷阱(就是認為在滿足某一情況的時候某一種操作一定更優)(但有些時候某些操作確實有更優情況,只不過這種題幾乎沒有),
我們可以直接選擇把三種情況簡化為數字的計算方式,直接寫入dp式中。、
通常情況下,這類有多種操作的dp題很大程度上都是在製造貪心的思維陷阱,因此最好直接把所有的情況直接轉化成數學計算式寫入dp轉移式中


程式碼:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int dp[2002][2002], INF = 1e9;
int main()
{
	int len1, len2;
	char a[2005], b[2005];
	scanf("%s%s", a+1, b+1); 
	len1 = strlen(a+1);
	len2 = strlen(b+1);
/*	for(int i = 1;i <= len1;i++)
	{
		for(int j = 1;j <= len2;j++)
		{
			dp[i][j] = INF;
		}
	}*/
	for(int i = 1;i <= max(len1,len2);i++)
	{
		dp[i][0] = i;
		dp[0][i] = i;	
	}//注意這裡的初始化的意義是當ij位置ab長度不同時,至少會進行abs(i - j)次更改
	for(int i = 1;i <= len1;i++)
	{
		for(int j = 1;j <= len2;j++)
		{
			if(a[i] == b[j])
			{
				dp[i][j] = dp[i-1][j-1];	
			}
			else
			{
				dp[i][j] = min(dp[i-1][j-1]+1,min(dp[i-1][j]+1,dp[i][j-1]+1));	
			}
		}
	}
	printf("%d", dp[len1][len2]);
	return 0;	
}