赞
踩
给定两个字符串str1和str2,再给定三个整数ic,dc和rc,分别代表插入、删除和替换一个字符的代价,请输出将str1编辑成str2的最小代价。
输出三行,第一行和第二行均为一行字符串,分别表示两个字符串str1,str2。(1≤length(str1),length(str2)≤5000)。第三行为三个正整数,代表ic,dc和rc。(1<=ic<=10000、1<=dc<=10000、1<=rc<=10000)
输出一个整数,表示编辑的最小代价。
示例1
abc adc 5 3 2
2
示例2
abc adc 5 3 100
8
示例3
abc abc 5 3 2
0
时间复杂度O(n∗m),空间复杂度O(n)。(n,m代表两个字符串长度)
- //方法1:
- //dp[i][j]定义为s1[0..i-1]编辑成s2[0..j-1]的最小代价
- //O(mn) O(mn)
- #include<bits/stdc++.h>
- using namespace std;
- int main(){
- string s1,s2;
- cin>>s1>>s2;
- int ic,dc,rc;
- cin>>ic>>dc>>rc;
-
- int row=s1.size()+1;
- int col=s2.size()+1;
- vector<vector<int>> dp(row,vector<int>(col,0));
- for(int i=1;i<row;i++){
- dp[i][0]=i*dc;
- }
- for(int j=1;j<col;j++){
- dp[0][j]=j*ic;
- }
- for(int i=1;i<row;i++){
- for(int j=1;j<col;j++){
- if(s1[i-1]==s2[j-1]){
- dp[i][j]=dp[i-1][j-1];
- }else{
- dp[i][j]=dp[i-1][j-1]+rc;
- }
- dp[i][j]=min(dp[i][j],dp[i][j-1]+ic);
- dp[i][j]=min(dp[i][j],dp[i-1][j]+dc);
- }
- }
- cout<<dp[row-1][col-1]<<endl;
- return 0;
- }

- //方法2:优化空间
- //dp[i][j]依赖于dp[i-1][j-1]、dp[i-1][j]、dp[i][j-1]
- //O(mn) O(min(m,n))
- #include<bits/stdc++.h>
- using namespace std;
- int main(){
- string s1,s2;
- cin>>s1>>s2;
- int ic,dc,rc;
- cin>>ic>>dc>>rc;
-
- //较短的字符串作为列
- if(s1.size()<s2.size()){ //s2较长就交换ic和dc的值
- swap(ic,dc);
- swap(s1,s2); //s1作为行,s2作为列(交换后,s2较短)
- }
- vector<int> dp(s2.size()+1);
- for(int j=1;j<=s2.size();j++){
- dp[j]=j*ic;
- }
- for(int i=1;i<=s1.size();i++){
- int pre=dp[0]; //pre表示上一行最左边的值,最开始是未更新的dp[0]
- dp[0]=i*dc; //更新当前行的dp[0]
- for(int j=1;j<=s2.size();j++){
- int tmp=dp[j]; //记录上一行的dp[j]
- if(s1[i-1]==s2[j-1]){
- dp[j]=pre;
- }else{
- dp[j]=pre+rc;
- }
- dp[j]=min(dp[j],dp[j-1]+ic);
- dp[j]=min(dp[j],tmp+dc);
- pre=tmp; //pre变为上一行的dp[j],是下一次循环的左上角的值
- }
- }
- cout<<dp[s2.size()]<<endl;
- return 0;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。