动态规划(2)

本文解析了三道经典的动态规划题目:编辑距离问题、最长递增子序列问题以及背包问题。通过具体实例和代码实现,深入浅出地介绍了动态规划算法的设计思路与应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接下来就是一些常见的动态规划题目:

(1)

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

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

测试样例:
"abc",3,"adc",3,5,3,100
返回:8
题目分析: 这是标准的动态规划题目。建立dp[n+1][m+1]数组。dp[i][j]表示字符串A[0,1,2....i]到B[0,1,2...j]的变换所用的最小代价。dp[0][i]与dp[j][0]则是表示A空字符串变成B字符串的代价和A字符串变成空串的代价。说明多加了一行和一列且都为空字符。则对于任意的一点(i,j)。其dp[i][j]的式子由下面的情况决定

    (1)当A[i-1]==B[j-1]时,说明(i,j)这个点的值,来自下面的三个方向(i-1,j),(i,j-1),(i-1,j-1)。如图:

   

   则dp[i][j]等于dp[i-1][j-1] ,dp[i-1][j]+c1,dp[i][j-1]+c0中的最小值

(2)A[i-1]!=B[j-1]时:

   则dp[i][j]等于dp[i-1][j-1] +c2,dp[i-1][j]+c1,dp[i][j-1]+c0中的最小值

程序:

int findMinCost(string A, int n, string B, int m, int c0, int c1, int c2) {
        vector<vector<int> > dp(n+1,vector<int> (m+1,0));// write code here
        dp[0][0] = 0;
        for(int i=1;i<n+1;i++){
            dp[i][0] = i*c1;
        }
        for(int j=1;j<m+1;j++){
            dp[0][j] = j*c0;
        }
        for(int i=1;i<n+1;i++){
            for(int j=1;j<m+1;j++){
                if(A[i-1] == B[j-1]){
                    dp[i][j] = dp[i-1][j-1];
                }else{
                    int min = (dp[i-1][j]+c1) < (dp[i][j-1]+c0) ? (dp[i-1][j]+c1) : (dp[i][j-1]+c0);
                    dp[i][j] = min < (dp[i-1][j-1]+c2) ? min : (dp[i-1][j-1]+c2);
                }
            }
        }
        return dp[n][m];
    }

  (2)

     

这是一个经典的LIS(即最长上升子序列)问题,请设计一个尽量优的解法求出序列的最长上升子序列的长度。

给定一个序列A及它的长度n(长度小于等于500),请返回LIS的长度。

测试样例:
[1,4,2,5,3],5
返回:3
程序
int getLIS(vector<int> A, int n) {
        // write code here
        vector<int> dp(n,0);
        dp[0]=1;   
        int len=1,i,j;
        for(i=1;i<n;i++){
            for(j=0;j<i;j++){
                if(A[i]>A[j])
                    dp[i]=max(dp[i],dp[j]);
            }
            dp[i]++;
            len=max(len,dp[i]);
        }
        return len;
    }

(3)

一个背包有一定的承重cap,有N件物品,每件都有自己的价值,记录在数组v中,也都有自己的重量,记录在数组w中,每件物品只能选择要装入背包还是不装入背包,要求在不超过背包承重的前提下,选出物品的总价值最大。

给定物品的重量w价值v及物品数n和承重cap。请返回最大总价值。

测试样例:
[1,2,3],[1,2,3],3,6
返回:6
程序:
 int maxValue(vector<int> w, vector<int> v, int n, int cap) {
        // write code here
        vector<int> dp(cap+1,0);
        for(int i=0;i<n;i++){
            for(int j=cap;j>=w[i];j--){
                dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
            }
        }
              
        return dp[cap];
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值