编辑距离(洛谷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;
}