题解 P2453 【[SDOI2006]最短距离】
变量c_xxx意为cost_xxx
之后的dp方程就很清晰了,萌新似乎也能看懂(初学OI系列)
kill放到最后统一处理,把各种情况kill到零,比较输出最大值即可
注意!dp[lena][lenb]必须在外面处理,因为ta不用kill,所以不用-1
(我一开始就被坑了,我还是太菜)
#include<bits/stdc++.h>
using namespace std;
int dp[210][210],lena,lenb,ans;//dp[i][j]表示a删i个,b到j个的最小值
int c_delete,c_replace,c_copy,c_insert,c_twiddle;
char a[210],b[210];
int main()
{
cin>>a>>b;
lena=strlen(a);
lenb=strlen(b);
cin>>c_delete>>c_replace>>c_copy>>c_insert>>c_twiddle;
for(int i=1;i<=max(lena,lenb);i++)
{
dp[0][i]=c_insert*i;
dp[i][0]=c_delete*i;
}
for(int i=1;i<=lena;i++)
{
for(int j=1;j<=lenb;j++)
{
dp[i][j]=999999999;//初始化
}
}
for(int i=1;i<=lena;i++)
{
for(int j=1;j<=lenb;j++)
{
dp[i][j]=min(dp[i][j],dp[i-1][j]+c_delete);
dp[i][j]=min(dp[i][j],dp[i-1][j-1]+c_replace);
if(a[i-1]==b[j-1])//我是从0读入的,所以减1
{
dp[i][j]=min(dp[i][j],dp[i-1][j-1]+c_copy);
}
dp[i][j]=min(dp[i][j],dp[i][j-1]+c_insert);
if(i>=2&&j>=2&&a[i-1]==b[j-2]&&a[i-2]==b[j-1])//不判前两个会炸
{
dp[i][j]=min(dp[i][j],dp[i-2][j-2]+c_twiddle);
}
}
}
ans=dp[lena][lenb];
for(int i=0;i<lena;i++)
{
ans=min(ans,dp[i][lenb]+(lena-i)*c_delete-1);
}
cout<<ans;
}