美文网首页
动态规划的3个例子 最长序列 背包问题

动态规划的3个例子 最长序列 背包问题

作者: 饱饱想要的灵感 | 来源:发表于2023-11-02 09:41 被阅读0次

1 最大子序和

题目: 给定一个整数数组nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

思路:

  1. 定义一个一维数组dp,其中dp[i]表示以第i个元素为结尾的最大子序和。
  2. 状态转移方程为dp[i] = max(dp[i-1]+nums[i], nums[i]),即用上一个位置的最大子序和和当前元素nums[i]相加,或者只选当前元素都可以得到一个以当前位置结尾的最大子序和。

Java代码实现:

public int maxSubArray(int[] nums) {
    int n = nums.length;
    int[] dp = new int[n];
    dp[0] = nums[0];
    int max = nums[0];
    for (int i = 1; i < n; i++) {
        dp[i] = Math.max(dp[i-1]+nums[i], nums[i]);
        max = Math.max(max, dp[i]);
    }
    return max;
}

2 最长上升子序列

题目: 在一个未排序的整数数组中,找到最长的上升子序列的长度。

思路:

  1. 注意审题, 这是最长的上升子序列, 不需要连续
  2. 定义一个一维数组dp,其中dp[i]表示以第i个元素为结尾的最长上升子序列的长度
  3. 所有元素初始状态为1,因为每个元素本身也构成一个长度为1的上升子序列。
  4. 然后遍历数组,对于当前元素nums[i],如果存在一个位置j在0 ~ i-1 之间,且nums[j]小于nums[i],那么将 dp[i] 更新为 dp[j]+1
  5. 用一个变量记录全局最大的dp值。

Java代码实现:

public int lengthOfLIS(int[] nums) {
    int n = nums.length;
    int[] dp = new int[n];
    Arrays.fill(dp, 1);
    int max = 1;
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < i; j++) {
            if (nums[j] < nums[i]) {
                dp[i] = Math.max(dp[i], dp[j]+1);
            }
        }
        max = Math.max(max, dp[i]);
    }
    return max;
}



此处, 可以引出问题的变种: 在一个未排序的整数数组中,找到最长的连续上升子序列的长度。

思路:

  1. 注意审题, 与上面区别, 此处是求这是最长连续的上升子序列
  2. 定义一个一维数组dp,其中dp[i]表示以第i个元素为结尾的最长连续上升子序列的长度
  3. 所有元素初始状态为1,因为每个元素本身也构成一个长度为1的上升子序列。
  4. 然后遍历数组,如果nums[i] > nums[i-1], 那么将 dp[i] 更新为 dp[i-1]+1
  5. 另外用一个变量记录全局最大的dp值。

依旧是Java代码实现:

public int longestRiseSerial(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int n = nums.length;
        int[] dp = new int[n];
        Arrays.fill(dp, 1);
        int maxLen = 0;
        for (int i = 1; i < n; i++) {
            if (nums[i] > nums[i - 1]) {
                dp[i] = dp[i - 1] + 1;
            }
            maxLen = Math.max(maxLen, dp[i]);
        }
        return maxLen;
    }

3 背包问题

题目: 有一个背包,容量为C,有n个物品,每个物品的重量为w[i],价值为v[i]。如何在保证装入背包的物品总重量不超过C的情况下,使得装入的物品总价值最大?

思路:

  1. 定义一个二维数组dp[i][j],其中dp[i][j]表示前i个物品中,背包容量为j时的最大价值。
  2. 若当前考虑的物品i的重量w[i]大于当前背包容量j,则dp[i][j] = dp[i-1][j](不将此物品装入背包),
  3. 否则dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i])(将此物品装入背包,可以用上一级商品的价值加上当前商品的价值)

Java代码实现:

public int knapsack(int[] w, int[] v, int C, int n) {
    int[][] dp = new int[n+1][C+1];
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= C; j++) {
            if (w[i-1] > j) {
                dp[i][j] = dp[i-1][j];
            } else {
                dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-w[i-1]] + v[i-1]);
            }
        }
    }
    return dp[n][C];
}



动态规划总结小笔记:

  1. 对于动态规划的一维数组, 通常由一个变量组成问题, dp[i]表示结果, 其中i表示包括前i个变量

  2. 对于动态规划的二维数组, 通常由两个变量组成问题, dp[i][j]表示结果, 其中i表示包括前i个变量一, 而j表示变量二为j

相关文章

  • Algorithm进阶计划 -- 动态规划(下)

    经典动态规划背包问题最长子序列问题 1. 背包问题 1.1 0-1 背包问题 0-1 背包问题,描述如下: 上面...

  • 最长公共子序列

    动态规划合集: 1.矩阵链乘法2.投资组合问题3.完全背包问题4.01背包问题5.最长公共子序列 例题5——最长公...

  • 背包问题(完全背包)

    动态规划合集: 1.矩阵链乘法2.投资组合问题3.完全背包问题4.01背包问题5.最长公共子序列 例题3——背包问...

  • 矩阵链的乘法问题

    动态规划合集: 1.矩阵链乘法2.投资组合问题3.完全背包问题4.01背包问题5.最长公共子序列 例题1——矩阵链...

  • 投资组合问题

    动态规划合集: 1.矩阵链乘法2.投资组合问题3.完全背包问题4.01背包问题5.最长公共子序列 例题2——投资问...

  • 背包问题(01背包+leetcode416)

    动态规划合集: 1.矩阵链乘法2.投资组合问题3.完全背包问题4.01背包问题5.最长公共子序列 例题4——01背...

  • 2022-02-19 动态规划高频题专题【1】

    动态规划基本类型 dp基础 背包问题 打家劫舍 股票问题 子序列问题 进阶动态规划 深入理解动态规划过程 定义dp...

  • DP经典问题代码

    斐波那契数列 (动态规划的递归写法) 数塔问题 (动态规划的递推写法) 最大连续子序列和 最长不下降子序列 最长公...

  • LCS:最长公共子序列

    LCS(最长公共子序列)是动态规划里的一道经典的问题。动态规划

  • 动态规划常见面试题

    子序列类型编辑距离 最长递增子序列 最大子数组 最长公共子序列 背包问题0-1背包问题 子集背包问题 完全背包问题...

网友评论

      本文标题:动态规划的3个例子 最长序列 背包问题

      本文链接:https://www.haomeiwen.com/subject/eztnidtx.html