Typesetting math: 100%
Evanyou Blog 彩带

P2453 [SDOI2006]最短距离

题目描述

一种EDIT字母编辑器,它的功能是可以通过不同的变换操作可以把一个源串X [l..m]变换为新的目标串y[1..n]。EDIT提供的变换操作有:

源串中的单个字符可被删除(delete);

被替换 (replace);

被复制到目标串中去(copy);

字符也可被插入(insert);

源串中的两个相邻字符可进行交换并复制到目标串中去(twiddle);

在完成其它所有操作之后,源串中余下的全部后缀就可用删至行末的操作删除(kill)。

例如,将源"algorithm"转换成目标串"altruistic"的一种方法是采取下面的操作序列:

要达到这个结果还可能有其它一些操作序列。

操作delete,replace,copy,insert,twiddle和kill中每一个都有一个相联系的代价cost。例如

  1. cost(delete)=3;
  2. cost(replace)=6;
  3. cost(copy)=5;
  4. cost(insert)=4;
  5. cost(twiddle)=4;
  6. 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

编程任务:

给定两个序列x[1..m],y[1..n]和一些操作代价集合,X到Y的最短距离为将X转化为Y的最小的转换序列的代价。请给出一个算法来找出x[1..m]至y[1..n]的最短距离。

输入输出格式

输入格式:

第一行:源序列x[1..m]。(m<200)

第二行:目标序列y[1..n]。(n<200)

第三行:5个正整数(<100):分别是:delete 、replace 、copy、 insert、 twiddle的代价。

输出格式:

X到Y的最短距离(最小代价和)。

输入输出样例

输入样例#1: 
  1. algorithm
  2. altruistic
  3. 3 6 5 4 4
输出样例#1: 
  1. 48

 

Solution:

  本题线性dp。

  字符串dp套路,定义状态f[i][j]表示目标串匹配i个原串操作了j个的最小代价,并用w[i]表示各操作的花费。

  那么初始状态:f[0][i1n]=w[1]i(删除原串前i个字符),f[i1m][0]=w[4](插入目标串前i个字符)。

  那么转移(取min):

    1、删除:f[i][j]=f[i][j1]+w[1]

    2、替换:f[i][j]=f[i1][j1]+w[2]

    3、复制:前提s[i]==t[j],则f[i][j]=f[i1][j1]+w[3]

    4、插入:f[i][j]=f[i1][j]+w[4]

    5、复制交换:前提s[i1]==t[j]s[i]==t[j1],则f[i][j]=f[i2][j2]+w[5]

  最后的时候还得对目标串匹配完了而原串操作到i位置进行后缀删除,即f[m][i]=f[m][i]+(ni)w[6]1

代码:

 

复制代码
  1. /*Code by 520 -- 10.15*/
  2. #include<bits/stdc++.h>
  3. #define il inline
  4. #define ll long long
  5. #define RE register
  6. #define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
  7. #define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
  8. using namespace std;
  9. const int N=205;
  10. int n,m,f[N][N],w[6];
  11. char s[N],t[N];
  12. int main(){
  13. ios::sync_with_stdio(0);
  14. memset(f,0x3f,sizeof(f));
  15. cin>>s+1>>t+1,n=strlen(s+1),m=strlen(t+1);
  16. For(i,1,5) cin>>w[i];
  17. f[0][0]=0;
  18. For(i,1,n) f[0][i]=w[1]*i;
  19. For(i,1,m) f[i][0]=w[4]*i;
  20. For(i,1,m) For(j,1,n){
  21. f[i][j]=min(f[i][j],f[i][j-1]+w[1]);
  22. f[i][j]=min(f[i][j],f[i-1][j-1]+w[2]);
  23. if(t[i]==s[j]) f[i][j]=min(f[i][j],f[i-1][j-1]+w[3]);
  24. f[i][j]=min(f[i][j],f[i-1][j]+w[4]);
  25. if(i>1&&j>1&&t[i]==s[j-1]&&t[i-1]==s[j]) f[i][j]=min(f[i][j],f[i-2][j-2]+w[5]);
  26. }
  27. int ans=0x3f3f3f3f;
  28. For(i,1,n-1) ans=min(ans,f[m][i]+(n-i)*w[1]-1);
  29. cout<<min(ans,f[m][n]);
  30. return 0;
  31. }
复制代码

 

 

 

posted @   five20  阅读(265)  评论(0编辑  收藏  举报
编辑推荐:
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
阅读排行:
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· 软件产品开发中常见的10个问题及处理方法
· Vite CVE-2025-30208 安全漏洞
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· MQ 如何保证数据一致性?
Live2D
欢迎阅读『P2453 [SDOI2006]最短距离』
点击右上角即可分享
微信分享提示