把a通过若干操作变成b
同样有一个状态集合f[i][j]、、、、、f[i][j]表示a[1~i]->b[1~j]的操作次数的集合
显然它的属性是min
接下来我们看看如何划分这个集合
有题目可以知道有三种方式
1.删除
2.添加
3.修改
动态规划的一般都是从上一个状态开始找
如果我们是要删除a[i]的话那么前提条件就是a[1~i-1]==b[1~j]
也就是f[i][j]=f[i-1][j]+1;
如果是添加一个字符的话那么前提条件就是a[1~i]==b[1~j-1]
也就是f[i][j]=f[i][j-1]+1;
修改的话有必须是要a[i]!=b[j]才会进行修改
#include<iostream>
using namespace std;
const int N=1010;
char a[N],b[N];
int f[N][N];//f[i][j]表示a[1~i]->b[1~j]的操作次数的集合,显然它的属性是min
int n,m;
int main()
{
cin>>n>>a+1>>m>>b+1;
for(int i=1;i<=n;i++)f[i][0]=i;
for(int i=1;i<=m;i++)f[0][i]=i;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
f[i][j]=min(f[i-1][j],f[i][j-1])+1;//找出删除以及添加中的最小的那个操作次数
if(a[i]==b[j])f[i][j]=min(f[i][j],f[i-1][j-1]);//如果相等的话就不需要+1
else f[i][j]=min(f[i][j],f[i-1][j-1]+1);//否则+1
}
cout<<f[n][m]<<endl;
return 0;
}
再讲一下初始化,如果把a变成一个长度为0的串也就是串那么它的操作次数就是a的长度
如果a是空串那么它的操作次数就是b的长度