1 条题解
-
0
自动搬运
来自洛谷,原作者为

LingFengGold
**搬运于
2025-08-24 21:37:51,当前版本为作者最后更新于2018-09-26 16:20:25,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
宣传一下博客~~~
状态:f[i][j]表示初始串初始串删除到第i个字符,目标串完成到第j个字符;
初始串为s1,len1;
目标串为s2,len2;
边界:
c[i][0]=cost(delet)*i;(目标串没有字符,初始串只能全删了)
c[0][j]=cost(insert)*j;(初始串一个字符都没有,目标串只能用insert一个一个插进去)
枚举i,枚举j
Copy:当a[i]==b[j]时(此条件需要判断),一样的话就copy就好;
c[i][j]=min(c[i][j],c[i-1][j-1]+cost[copy]);
Repalce:当a[i]!=b[j]时(此条件无需判断),就把初始串的删了,目标串填一个;
c[i][j]=min(c[i][j],c[i-1][j-1]+cost[replace]);
Delet:是删除一个初始串的,对于目标串无影响;
c[i][j]=min(c[i][j],c[i-1][j]+cost[delet]);
Insert:给目标串多完成一个,对初始串无影响;
c[i][j]=min(c[i][j],c[i][j-1]+cost[insert]);
Twiddle:当a[i-1]==b[j]&&a[i]==b[i-1]&&i>=2&&j>=2时(此条件需要判断),就twiddle;
c[i][j]=min(c[i][j],c[i-2][j-2]+cost[twiddle]);
枚举结束!
Kill:单独拿出来,枚举当目标串已经完成的情况下(i=len2),初始串要清零的最小值
c[len1][len2]=min(c[len1][len2],c[i][len2]+cost[delet]*(len1-i)-1);
结果:f[len1][len2]。
上面解释的很清楚,附上代码。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<stack> #define inf 1e18+5 #define ll long long using namespace std; ll inline read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } char a[2050],b[2050]; ll c[2050][2050]; ll cost[6]; int main() { scanf("%s%s",a+1,b+1); for(int i=1;i<=5;i++){ cost[i]=read(); } //1=delet,2=replace,3=copy,4=insert,5=twiddle int len1=strlen(a+1),len2=strlen(b+1); if(len1==0&&len2==0){ printf("0"); return 0; } if(len1==0&&len2!=0){ printf("%lld",len2*cost[4]); return 0; } if(len1!=0&&len2==0){ printf("%lld",len1*cost[1]); return 0; } for(int i=1;i<=len1;i++){ for(int j=1;j<=len2;j++){ c[i][j]=inf; } } c[0][0]=0; for(int i=1;i<=len1;i++){ c[i][0]=i*cost[1]; } for(int i=1;i<=len2;i++){ c[0][i]=i*cost[4]; } for(int i=1;i<=len1;i++){ for(int j=1;j<=len2;j++){ if(a[i]==b[j]){ c[i][j]=min(c[i][j],c[i-1][j-1]+cost[3]); } c[i][j]=min(c[i][j],c[i-1][j-1]+cost[2]); c[i][j]=min(c[i][j],c[i-1][j]+cost[1]); c[i][j]=min(c[i][j],c[i][j-1]+cost[4]); if(i>=2&&j>=2&&a[i-1]==b[j]&&a[i]==b[j-1]){ c[i][j]=min(c[i][j],c[i-2][j-2]+cost[5]); } } } for(int i=1;i<len1;i++){ c[len1][len2]=min(c[len1][len2],c[i][len2]+cost[1]*(len1-i)-1); } printf("%lld",c[len1][len2]); return 0; }
- 1
信息
- ID
- 1484
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者