【题解】小S的货船租贷冒险 | 豆包MarsCode AI刷题

86 阅读2分钟

题目分析

需要在预算 V 内,选择不同类型的货船,使得总载货量最大化。每种货船有数量限制,租赁成本和载货量。

  1. 初始化 dp 数组dp[i][j] 表示在前 i 种货船中,预算为 j 时的最大载货量。
  2. 遍历每种货船:对于每种货船,考虑选择0到m[i]艘货船的情况。
  3. 更新 dp 数组:在每种预算下,更新 dp 数组,考虑选择不同数量的货船。

解题思路

  • 初始化 dp 数组,dp[0][j] = 0 表示没有货船时,无论预算多少,载货量都是0。
  • 对于每种货船,考虑选择0到m[i]艘货船的情况,更新 dp 数组。
  • 最终答案就是 dp[Q][V],即在前 Q 种货船中,预算为 V 时的最大载货量。

java代码

public class Main {
public static int solution(int Q, int V, List<List<Integer>> ships) {
    // 初始化dp数组,dp[i][j]表示在前i种货船中,预算为j时的最大载货量
    int[][] dp = new int[Q + 1][V + 1];

    // 遍历每种货船
    for (int i = 1; i <= Q; i++) {
        int m = ships.get(i - 1).get(0); // 货船数量
        int v = ships.get(i - 1).get(1); // 租赁成本
        int w = ships.get(i - 1).get(2); // 载货量

        // 遍历预算
        for (int j = V; j >= 0; j--) {
            // 考虑选择0到m艘货船的情况
            for (int k = 0; k <= m && k * v <= j; k++) {
                // 更新dp数组
                dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - k * v] + k * w);
            }
        }
    }

    // 返回最大载货量
    return dp[Q][V];
}

public static void main(String[] args) {
    // 测试用例
    List<List<Integer>> ships = new ArrayList<>();
    ships.add(List.of(2, 3, 2));
    ships.add(List.of(3, 2, 10));

    System.out.println(solution(2, 10, ships) == 32);
}
}

动态规划思想

这种解决问题的方式很好地体现了动态规划的思想,通过将大问题分解为子问题,并利用子问题的解来构建大问题的解。通过逐步考虑每种货船的选择情况,在不同的预算限制下计算最大载货量,最后得到整体的最优解。

  • 时间复杂度

    • 有三层嵌套的循环。外层循环遍历Q种货船,中层循环遍历预算V,内层循环最多遍历m艘货船。所以总的时间复杂度是𝑂(𝑄∗𝑉∗𝑚)O(Q∗V∗m)。
  • 空间复杂度

    • 创建了一个大小为(Q + 1) * (V + 1)的二维数组dp来存储中间结果。如果QV的值很大,可能会占用较多的内存空间。考虑优化空间复杂度,例如使用滚动数组来减少空间占用,因为在计算dp[i][j]时,只需要用到dp[i - 1][*]的值,可以通过复用数组空间来优化。