P2758 编辑距离做题笔记

这题是昨天做的,写到一半打模拟赛了,断了网,没有存,顺带吐槽洛谷博客没有草稿箱,再加上今天上午也有模拟赛,所以咕咕咕到了现在才来写做题笔记。开始看题时一脸懵逼,可能是因为平时做 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}\) 推出,若 \(a_i = b_j\)\(s_{i,j} = s_{i-1,j-1}\),因为新加的 \(a_i\)\(b_j\) 之间无需转换,否则需要转换一次,状态转移方程为:\(s_{i,j} = min(s_{i-1,j},s_{i,j-1},s_{i-1,j-1})+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;
}
posted @ 2022-05-13 07:46  Jason142  阅读(19)  评论(0编辑  收藏  举报