动态规划合集

动态规划

思想

动态规划是一个通过把原问题分为几个子问题来解决复杂问题的工具。主要有自底向上和自顶向下两种方法。自底向上就是递推,自顶向下就是记忆化递归。

  • 什么样的题可以用动态规划来解决?
    • 求最优解问题(最大值/最小值)
    • 求可行性(truefalse)
    • 求方案总数

注意:有些问题可以用贪心/排序来解决,就可以不用动态规划。

  • 动态规划中的词汇
    • 子数组 连续序列中的最优解
    • 子序列 可以不是连续的序列中的最优解

动态规划思想例题:

数字三角形
它是一道带有动态规划思想的题目(和递推差不多)
它要求走到底部和最大,我们可以从底部开始推,每次找到下面两个中最大的一个,加到它自己身上,到最后,f[0][0]就是最大的了。

for(int i=n-2;i>=0;i--){
    for(int j=0;j<=i;j++){
        a[i][j]+=max(a[i+1][j],a[i+1][j+1]);
    }
}

背包问题

01背包
完全背包
多重背包
混合背包
分组背包
二维费用背包


其它动态规划

树形dp
区间dp


经典动态规划问题

编辑距离
我们设dp[i][j]表示word1的前i项和word2的前j项之间的编辑距离。
我们能进行的操作有三种

  • word1中插入一个字符
  • word2中插入一个字符
  • 修改word1中的一个字符

那么这样,就可以得出,状态转移方程为

int left=dp[i-1][j]+1;
int down=dp[i][j-1]+1;
int left_down=dp[i-1][j-1];
if(word1[i-1]!=word2[j-1]){
	left_down++;
}
dp[i][j]=min(left,min(left_down,down));

前面再将dp数组初始化一下,就得到了完整代码。

class Solution {
public:
    int minDistance(string word1, string word2) {
        int n=word1.size();
        int m=word2.size();
        if(n*m==0){
            return n+m;
        }
        vector<vector<int>> dp(n+1,vector<int>(m+1));
        for(int i=0; i<=n; i++){
            dp[i][0]=i;
        }
        for(int j=0; j<=m; j++){
            dp[0][j]=j;
        }
        for(int i=1; i<=n; i++){
            for(int j=1; j<=m; j++){
                int left=dp[i-1][j]+1;
                int down=dp[i][j-1]+1;
                int left_down=dp[i-1][j-1];
                if(word1[i-1]!=word2[j-1]){
                    left_down++;
                }
                dp[i][j]=min(left,min(left_down,down));
            }
        }
        return dp[n][m];
    }
};

连续子数组最大和
给你一个整数数组nums,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
子数组 是数组中的一个连续部分。
比如说一个数组的元素如下:

[2,1,3,4,1,2,1,5,4]

那么我们可以知道,连续子数组 [4,1,2,1] 的和最大,为6。

子数组是要求要是数组里的一段连续的,最大(最小)的一串数字。我们可以用动态规划来求出它。
那么我们可以用dp[i]来表示前i个数字中最大的一串数字
然后,就可以写出式子了。有两中情况,分别是把数字加进去比较大,还有一种就是数字本身比加进去要大(比如说dp[i]是负数),只要把dp[i]应当得到的最大值求出来就可以了。下面是重点代码部分

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int n=nums.size();//注意!vector的size返回的不是一个整形!
        vector<int> dp(n+1,0);
        int ans=nums[0];
        for(int i=1; i<=n; i++){
            dp[i]=max(nums[i-1],dp[i-1]+nums[i-1]);
            ans=max(ans,dp[i]);
        }
        return ans;
    }
};
posted @   lwr2010  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示