【SDOI2006]最短距離

タイトル説明

EDITエディタ文字の一種、その操作がX [l..m]新しいターゲット文字列Y [1..nの]に変換され、変換異なるソース列で機能することが可能です。EDIT変換操作が提供されています。

ソース文字列内の単一の文字は、(削除)を削除することができます。

(交換)交換されます。

これは、(コピー)に先の文字列にコピーされます。

文字は、(INSERT)を挿入することができます。

隣接する二つの文字列のソースは交換して(回転因子)にターゲット文字列にコピーすることができます。

他のすべての操作が完了した後、残りのソースサフィックス文字列のすべての行の削除操作(キル)端を削除するために使用することができます。

たとえば、ソース「アルゴリズム」がターゲット文字列に変換され、「利他」の一つの方法は、次の一連の操作を取ることです。

この結果を達成するためにも、操作の他のいくつかの配列を有していてもよいです。

、削除、置換、コピー、挿入、コストの費用をひねり、それぞれ1がリンクされてい殺す操作します。例えば

cost(delete)=3;
cost(replace)=6;
cost(copy)=5;
cost(insert)=4;
cost(twiddle)=4;
cost(kill)=被删除的串长*cost(delete)-1;

各動作シーケンスおよび検討のための動作の所定のシーケンスのコスト。例えば、操作の上記配列の料金

3 *コスト(コピー)+ 2 *コスト(置き換え)+コスト(削除)+ 3 *コスト(挿入)+コスト(ひねり)+コスト(キル)

= 48 = * 4 * 6 * 5 3 + 2 + 3 + 3 + 4 + 1 * 3-1

プログラミングタスク:

二つの配列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):以下のとおりです、置き換え、コピー、挿入、責めのコストを削除します。

出力フォーマット

Yへの最短距離X(及び最小コスト)。

サンプル入力と出力

入力#1
アルゴリズム

利他

3 6 5 4 4
出力#1
48

【解题思路】

关于这种序列匹配的问题,思路都是一样的。

设f[i][j]表示目标串已经完成了前i位,初始串已经删除了j位。

边界:

f[0][j]=cost(delete)*j(因为目标串一位都没有,所以初始串只能删)

f[i][0]=cost(insert)*i(因为初始串一位也没动过,所以只能往目标串里添加)

对于每种操作:(设目标串为s2,初始串s1)

delete->f[i][j]=min(f[i][j],f[i][j-1]+cost(delete))
replace->f[i][j]=min(f[i][j],f[i-1][j-1]+cost(replace)) copy->f[i][j]=min(f[i][j],f[i-1][j-1]+cost(copy))(s2[i]==s1[j]) insert->f[i][j]=min(f[i][j],f[i-1][j]+cost(insert)) twiddle->f[i][j]=min(f[i][j],f[i-2][j-1]+cost(triddle))(s2[i]==s1[j-1]&&s2[i-1]==s1[j])

然后转移就好了,时间复杂度O(len(s1)*len(s2)) 最后枚举f[len(s2]j,把答案加上(len(s1)-j)*del-1;

然后和f[len(s2)][len(s1)]比较,所有的值里面取最小值。

【code】

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 int cop,tri,del,ins,rep;
 6 char s1[1001],s2[1001];
 7 int f[202][202];
 8 int ans;
 9 inline int min(int a,int b)
10 {
11     return a<b?a:b;
12 }
13 int main()
14 {
15     memset(f,127,sizeof(f));
16     scanf("%s",s1+1);
17     scanf("%s",s2+1);
18     f[0][0]=0;
19     scanf("%d%d%d%d%d",&del,&rep,&cop,&ins,&tri);
20     int m=strlen(s1+1),n=strlen(s2+1);
21     for(int i=1;i<=n;i++)
22     f[i][0]=i*ins;
23     for(int i=1;i<=m;i++)
24     f[0][i]=i*del;
25     for(int i=1;i<=n;i++)
26     for(int j=1;j<=m;j++)
27     {
28         f[i][j]=min(f[i][j],f[i][j-1]+del);
29         f[i][j]=min(f[i][j],f[i-1][j-1]+rep);
30         if(s2[i]==s1[j])
31         f[i][j]=min(f[i][j],f[i-1][j-1]+cop);
32         f[i][j]=min(f[i][j],f[i-1][j]+ins);
33         if(i>1&&j>1&&s2[i-1]==s1[j]&&s2[i]==s1[j-1])
34         f[i][j]=min(f[i][j],f[i-2][j-2]+tri);
35     }
36     ans=0x7fffffff;
37     for(int i=1;i<m;i++)
38     ans=min(ans,f[n][i]+(m-i)*del-1);
39     ans=min(ans,f[n][m]);
40     printf("%d",ans);
41 }

 

おすすめ

転載: www.cnblogs.com/66dzb/p/11259390.html