P2453 [SDOI2006] 最短距离题解
P2453 [SDOI2006] 最短距离
题目描述
一种 EDIT 字母编辑器,它的功能是可以通过不同的变换操作可以把一个源串 X[l⋯m]X[l\cdots m]X[l⋯m] 变换为新的目标串 Y[1⋯n]Y[1\cdots n]Y[1⋯n]。EDIT 提供的变换操作有:
- 删除源串首个字符(delete);
- 替换源串首个字符放到目标串末尾(replace)。replace 操作可以替换为与原来相同的字符;
- 移动源串首个字符放到目标串末尾(copy);
- 向目标串插入单个字符(insert);
- 交换源串中的两个相邻字符,并移动到目标串末尾中去(twiddle);
- 在完成其它所有操作之后,源串中余下的全部后缀就可用删至行末的操作删除(kill)。
例如,将源 algorithm 转换成目标串 altruistic 的一种方法是采取下面的操作序列:
| 操作 | 目标串 | 原串 |
|---|---|---|
| 初始 | (空) | algorithm |
copy a | a | lgorithm |
copy l | al | gorithm |
replace g to t | alt | orithm |
delete o | alt | rithm |
copy r | altr | ithm |
insert u | altru | ithm |
insert i | altrui | ithm |
insert s | altruis | ithm |
twiddle it into ti | altruisti | hm |
replace h to c | altruistic | m |
kill | altruistic | (空) |
要达到这个结果还可能有其它一些操作序列。
操作 delete、replace、copy、insert、twiddle 和kill中每一个都有一个相联系的代价 cost。例如:
cost(delete) =3;
cost(replace)=6;
cost(copy) =5;
cost(insert) =4;
cost(twiddle)=4;
cost(kill) = 被删除的串长 * cost(delete) - 1;
一个给定的操作序列的代价为序列中各操作代价之和。
例如上述操作序列的代价为
3×cost(copy)+2×cost(replace)+cost(delete)+3×cost(insert)+cost(twiddle)+cost(kill)= 3×5+2×6+3+3×4+4+1×3−1= 48\begin{aligned}&3\times \mathrm{cost}(\mathtt{copy})+2\times \mathrm{cost}(\mathtt{replace})+\mathrm{cost}(\mathtt{delete})+3\times \mathrm{cost}(\mathtt{insert}) \\ &+\mathrm{cost}(\mathtt{twiddle}) +\mathrm{cost}(\mathtt{kill}) \\ =\ & 3\times 5+2\times 6+3+3\times 4+4+1\times 3-1\\ =\ &48\end{aligned}= = 3×cost(copy)+2×cost(replace)+cost(delete)+3×cost(insert)+cost(twiddle)+cost(kill)3×5+2×6+3+3×4+4+1×3−148
编程任务
给定两个序列 X[1⋯m],Y[1⋯n]X[1\cdots m],Y[1\cdots n]X[1⋯m],Y[1⋯n] 和一些操作代价集合,XXX 到 YYY 的最短距离为将 XXX 转化为 YYY 的最小的转换序列的代价。请给出一个算法来找出 X[1⋯m]X[1\cdots m]X[1⋯m] 至 Y[1⋯n]Y[1\cdots n]Y[1⋯n] 的最短距离。
输入格式
第一行:源序列 X[1⋯m]X[1\cdots m]X[1⋯m]。
第二行:目标序列 Y[1⋯n]Y[1\cdots n]Y[1⋯n]。
第三行:555 个正整数,分别是:delete、replace、copy、insert、twiddle 的代价。
输出格式
一行一个整数,表示 XXX 到 YYY 的最短距离(最小代价和)。
输入输出样例 #1
输入 #1
algorithm
altruistic
3 6 5 4 4
输出 #1
48
说明/提示
数据范围及约定
对于全部数据,满足 1≤n,m≤2001\le n,m\le 2001≤n,m≤200,且所有代价均为不大于 100100100 的非负整数。
思路
DP即可。
代码见下
#include<bits/stdc++.h>
using namespace std;
string s1,s2;
char a[200005],b[200005];
long long n=0,m=0,de,re,co,in,tw,f[2005][2005],op=1e18+7;
int main(){
cin>>s2>>s1;
cin>>de>>re>>co>>in>>tw;
for(int i=0;i<s1.size();i++){
a[++n]=s1[i];
}
for(int j=0;j<s2.size();j++){
b[++m]=s2[j];
}
memset(f,63,sizeof(f));
f[0][0]=0;
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
if(j+1<=m){
f[i][j+1]=min(f[i][j+1],f[i][j]+de);
}
if(i+1<=n&&j+1<=m){
f[i+1][j+1]=min(f[i+1][j+1],f[i][j]+re);
}
if(i+1<=n&&j+1<=m&&a[i+1]==b[j+1]){
f[i+1][j+1]=min(f[i+1][j+1],f[i][j]+co);
}
if(i+1<=n){
f[i+1][j]=min(f[i+1][j],f[i][j]+in);
}
if(i+2<=n&&j+2<=m&&a[i+1]==b[j+2]&&a[i+2]==b[j+1]){
f[i+2][j+2]=min(f[i+2][j+2],f[i][j]+tw);
}
}
}
cout<<min(f[n][m-1]+de-1,f[n][m])<<endl;
return 0;
}

浙公网安备 33010602011771号