问题83 小S在码头租赁冒险 | 豆包MarsCode AI刷题

15 阅读2分钟
问题描述

小S在码头租用货船,有 Q 种不同类型的货船可供选择。每种货船有固定的数量 m[i]、租赁成本 v[i] 和最大载货量 w[i]。小S希望在预算 V 元内,租用能够承载最大总货物的货船组合。每种货船的具体信息包括数量、租赁价格和载货量。小S需要你帮忙计算在给定预算下,她能租用的货船的最大总载货量是多少。

  • Q: 货船的种类数量。
  • V: 李华可用的总预算(单位:元)。
  • ships: 一个列表,其中每个元素是一个元组 [m[i], v[i], w[i]],分别表示第 i 种货船的数量、租赁价格和每艘货船的最大载货量。
思路

首先,当仅仅有一种船时,容易得到答案

然后,假设我们知道对于k种船,预算为任意x (x >= 0, x <= V, x 为整数)时的答案。不妨叫这个答案f(k,x)。

考虑如果在这个基础上,我们多了一个货船的选项之后(其值为数量n,费用v,载重w)对于任意预算x,其答案f(k+1,x)所对应的租船策略。

假定最优策略里租用了y艘新加入的种类的船,则可得:

  • y >= 0 , y <= min(x/v, n),提供的载重量为 y * w
  • 租用前k种船的预算为 x - y*v 元,提供的载重量(最多)为 f(k,x - y * v)

所以可知 f(k+1,x) = f(k,x-yv) + yw

重复以上思路,我们便可以得到这道题的解答

代码示例
int solution(int Q, int V, vector<vector<int>> ships) {
    vector<int> dp(V + 1, 0); 

    for (auto ship : ships) {
        int n_max = ship[0], p = ship[1], w = ship[2];
        for (int v=V;v>=0;v--) {
            for(int n=0;n<=min(n_max,v/p);n++) {
                dp[v] = max(dp[v],dp[v - n*p] + n * w);
            }
        }
    }

    return dp[V];
}
代码示例

int solution(int Q, int V, vector<vector> ships) { vector dp(V + 1, 0);

for (auto ship : ships) {
    int n_max = ship[0], p = ship[1], w = ship[2];
    for (int v=V;v>=0;v--) {
        for(int n=0;n<=min(n_max,v/p);n++) {
            dp[v] = max(dp[v],dp[v - n*p] + n * w);
        }
    }
}

return dp[V];

} int solution(int Q, int V, vector<vector> ships) { vector dp(V + 1, 0);

for (auto ship : ships) {
    int n_max = ship[0], p = ship[1], w = ship[2];
    for (int v=V;v>=0;v--) {
        for(int n=0;n<=min(n_max,v/p);n++) {
            dp[v] = max(dp[v],dp[v - n*p] + n * w);
        }
    }
}

return dp[V];

} int solution(int Q, int V, vector<vector> ships) { vector dp(V + 1, 0);

for (auto ship : ships) {
    int n_max = ship[0], p = ship[1], w = ship[2];
    for (int v=V;v>=0;v--) {
        for(int n=0;n<=min(n_max,v/p);n++) {
            dp[v] = max(dp[v],dp[v - n*p] + n * w);
        }
    }
}

return dp[V];

}