学习交流加

  • 个人qq:
    1126137994
  • 个人微信:
    liu1126137994
  • 学习交流资源分享qq群:
    962535112

对于两个字符串A和B,我们需要进行插入、删除和修改操作将A串变为B串,定义c0,c1,c2分别为三种操作的代价,请设计一个高效算法,求出将A串变为B串所需要的最少代价。

给定两个字符串A和B,及它们的长度和三种操作代价,请返回将A串变为B串所需要的最小代价。保证两串长度均小于等于300,且三种代价值均小于等于100。

测试样例:
“abc”,3,“adc”,3,5,3,100
返回:8

解题思路:
假设A的长度为n,B的长度为m,首先生成一个dp矩阵,dp[n+1]m+1,dp[i][j]代表将A[0(i-1)]变成B[0(j-1)]的最小代价。
1、先求第一行:
dp[0][j],将空串变成B[0…j-1],直接一个一个插入:

for(int j=0;j<m+1;j++)
        {
            dp[0][j]=j*ic;//ic代表插入的操作的代价
        }

2、再求第一列:
将A[0…i-1]变成空串,直接一个一个删除:

for(int i=0;i<n+1;i++)
        {
            dp[i][0]=i*dc;//dc代表删除的操作代价
        }

3、求其他行的值:
求其他行的值,可以大致分为以下四种情况:

一、
先把A[0(i-1)]编辑成A[0(i-2)],也就是删除字符A[i-1],再将A[0(i-2)]编辑成B[0(j-1)],dp[i-1][j],所以:
dp[i][j]=dc+dp[i-1][j]

二、
先把A[0(i-1)]编辑成B[0(j-2)],即dp[i][j-1],再将B[0~(j-2)]插入B[j-1],所以:
dp[i][j]=ic+dp[i][j-1]

三、
如果A[i-1]!=B[j-1],那么先把A[0(i-2)]编辑成B[0(j-2)],然后把A[i-1]替换成B[j-1]即可!!!所以:
dp[i][j]=rc+dp[i-1][j-1];

四、
如果A[i-1]=B[j-1],那么直接把A[0(i-2)]编辑成B[0(j-2)],即可,所以:
dp[i][j]=dp[i-1][j-1];

选出以上四种情况的最小值,就是最终dp[i][j]的值。

综上编写程序如下:

class MinCost {
public:
    int findMinCost(string A, int n, string B, int m, int c0, int c1, int c2) {
        // write code here
        int ic=c0,dc=c1,rc=c2;
        int dp[n+1][m+1];
        //先求第一行dp[0][j],将空串变成B[0...j-1],直接一个一个插入
        for(int j=0;j<m+1;j++)
        {
            dp[0][j]=j*ic;
        }
        //再求第一列,将A[0...i-1]变成空串,直接一个一个删除
        for(int i=0;i<n+1;i++)
        {
            dp[i][0]=i*dc;
        }
        //再求其他行,从上到下,从左往右计算
        for(int i=1;i<n+1;i++)
        {
            for(int j=1;j<m+1;j++)
            {
                int Min_Num=min(dc+dp[i-1][j],ic+dp[i][j-1]);
                if(A[i-1]!=B[j-1])
                {
                    Min_Num=min(rc+dp[i-1][j-1],Min_Num);
                }
                else
                {
                    Min_Num=min(dp[i-1][j-1],Min_Num);
                }   
                dp[i][j]=Min_Num;
            }
        }
        return dp[n][m];
        
    }
};