A conveyor belt has packages that must be shipped from one port to another within D days.

The i-th package on the conveyor belt has a weight of weights[i].  Each day, we load the ship with packages on the conveyor belt (in the order given by weights). We may not load more weight than the maximum weight capacity of the ship.

Return the least weight capacity of the ship that will result in all the packages on the conveyor belt being shipped within D days.

Example 1:

Input: weights = [1,2,3,4,5,6,7,8,9,10], D = 5
Output: 15
Explanation:
A ship capacity of 15 is the minimum to ship all the packages in 5 days like this:
1st day: 1, 2, 3, 4, 5
2nd day: 6, 7
3rd day: 8
4th day: 9
5th day: 10 Note that the cargo must be shipped in the order given, so using a ship of capacity 14 and splitting the packages into parts like (2, 3, 4, 5), (1, 6, 7), (8), (9), (10) is not allowed.

Example 2:

Input: weights = [3,2,2,4,1,4], D = 3
Output: 6
Explanation:
A ship capacity of 6 is the minimum to ship all the packages in 3 days like this:
1st day: 3, 2
2nd day: 2, 4
3rd day: 1, 4

Example 3:

Input: weights = [1,2,3,1,1], D = 4
Output: 3
Explanation:
1st day: 1
2nd day: 2
3rd day: 3
4th day: 1, 1

Note:

  1. 1 <= D <= weights.length <= 50000
  2. 1 <= weights[i] <= 500

Idea 1. Start with easy case, assume d = 2, it means splitting the array in two parts so that the maximum sum of continuous subarray is the minimal, given example

weights = [3,2,2,4,1,4], D = 2, n = 6
k = 0, dp(0, 5) = max(prefix(0, 0), dp(1, 5)(1)) = max(3, 13) = 13
k = 1, dp(0, 5) = max(prefix(0, 1), dp(2, 5)(1)) = max(5, 11) = 11
k = 2, dp(0, 5) = max(prefix(0, 2), dp(3, 5)(1)) = max(7, 9) = 9
k = 3, dp(0, 5) = max(prefix(0, 3), dp(4, 5)(1)) = max(11, 5) = 11
k = 4, dp(0, 5) = max(prefix(0, 4), dp(5, 5)(1)) = max(12, 4) = 12
dp(0, 5) = min(13, 11, 9, 11, 12) = 9,splitting the array from k = 2, [3, 2, 2], [4,1,4] achieving the minimum load 9. how about d = 3?
k = 0, dp(0, 5) = max(prefix(0, 0), dp(1, 5)(d=2)) = max(3, 8) = 8
k = 1, dp(0, 5) = max(prefix(0, 1), dp(2, 5)(d=2)) = max(5, 6) = 6
k = 2, dp(0, 5) = max(prefix(0, 2), dp(3, 5)(d=2)) = max(7, 5) = 7
k = 3, dp(0, 5) = max(prefix(0, 3), dp(4, 5)(d=2)) = max(11, 4) = 11
dp(0, 5)(3) = min(8, 6, 7, 11) = 6

spliting the array from position k, if put all loads from weights(i, k) as the first day, weights(k+1, j) requires to be loaded within d-1 days, another subproblems, the relationship can be respresented as the formula, let dp(i, j)(d) be the minimum loads in d days:

dp(i, j)(d) = min(i<=k <= j-d+1)( max( prefix(i, k), dp(k+1, j)(d-1)) ))

如果某一段weights[i, j]用一天,需要计算subarray sum, 用一个prefixSum数组提前计算好

Time complexity: O(n3)

Space complexity: O(n2)

    private int calculateMinCapacity(int i, int j, int d,
int[] prefixSum, int[][] dp) {
int minCapacity = Integer.MAX_VALUE; for(int k = i; k <= j-d+1; ++k) {
int next = ((d == 2)? prefixSum[j+1] - prefixSum[k+1] : dp[k+1][j]);
int val = Math.max(prefixSum[k+1] - prefixSum[i], next);
minCapacity = Math.min(minCapacity, val);
}
return minCapacity;
} public int shipWithinDays(int[] weights, int D) {
int n = weights.length;
int[] prefixSum = new int[n+1];
for(int i = 1; i <= n; ++i) {
prefixSum[i] = prefixSum[i-1] + weights[i-1];
} int[][] dp = new int[n][n]; if(D == 1) {
return prefixSum[n];
} for(int d = 2; d <= D; ++d) {
for(int i = 0; i < n; ++i) {
for(int j = i+d-1; j < n; ++j) {
//for(int j = n-1; j>= i+d-1; --j) {
dp[i][j] = calculateMinCapacity(i, j, d, prefixSum, dp);
}
}
}
return dp[0][n-1];
}

Idea 1.b. 从上面的公式可以看出j是固定的n-1, 可以变成一维的dp

dp(i)(d) = min(i <= k <= j-d+1)(max(prefixSum(i, k), dp(k+1)(d-1)))

Time complexity: O(n2)

Space complexity: O(n)

 class Solution {
private int calculateMinCapacity(int i,int d,
int[] prefixSum, int[] dp) {
int minCapacity = Integer.MAX_VALUE;
int n = dp.length;
for(int k = i; k <= n-d; ++k) {
int next = ((d == 2)? prefixSum[n] - prefixSum[k+1] : dp[k+1]);
int val = Math.max(prefixSum[k+1] - prefixSum[i], next);
minCapacity = Math.min(minCapacity, val);
}
return minCapacity;
} public int shipWithinDays(int[] weights, int D) {
int n = weights.length;
int[] prefixSum = new int[n+1];
for(int i = 1; i <= n; ++i) {
prefixSum[i] = prefixSum[i-1] + weights[i-1];
} if(D == 1) {
return prefixSum[n];
}
if(D == n) {
return Arrays.stream(weights).max().getAsInt();
} int[] dp = new int[n];
for(int d = 2; d <= D; ++d) {
for(int i = 0; i <= n-d; ++i) {
dp[i]= calculateMinCapacity(i, d, prefixSum, dp);
}
} return dp[0];
}
}

Idea 2. 啊 竟然有binary search的妙法。确定search space: [max(weights[i]), sum(weights[i])], 这题是求

least weigth capacity, 即使找到第一个满足D days的weight, 不确定是否更小的也满足条件,所以要继续包括在search space中,就像寻找有duplicates的数组里第一个等于目标的index 还有网上看到的优化, 最小值设为max(sum(weights[i])/D, max(weights[i])), 如果数组里有很多小数,这个可以进一步的narrow down search space.

Note: 1. 特别容易混淆== 放哪边,days > D, move the search space to the rights, as the searched mid load is too small and it takes more days to finish the load, rule out mid load, move the search space from mid+1

    days <= D, even it's == D, there might be smaller load like mid-1 or mid-2 satisfy the conidition, move the search space to the right, upperbounded by mid, similar direction as the mid load is too large and it takes less days to finish the load and continue to seach the smaller load.

   2. sum + weight > load, 这个包括当前sum == load, 在前面sum的时候分割, 天数比分割数多一,初始化days=1, 这2个细节谨记 

Time complexity: nlog(mn), n is the length of weights, m is the maximum elements in weights,  checkdays takes n steps, which is executed during each binary search in the range(max(weights), sum(weights)).

Space complexity: O(1)

 class Solution {
private int checkDays(int[] weights, int load) {
int sum = 0;
int days = 1;
for(int weight: weights) {
if(sum + weight > load) {
++days;
sum = weight;
}
else {
sum += weight;
}
} return days;
} public int shipWithinDays(int[] weights, int D) {
int n = weights.length;
int minLoad = 0, maxLoad = 0;
for(int weight: weights) {
minLoad = Math.max(minLoad, weight);
maxLoad += weight;
} if(D == 1) {
return maxLoad;
}
if(D >= n) {
return minLoad;
} while(minLoad < maxLoad) {
int mid = minLoad + (maxLoad - minLoad)/2;
int days = checkDays(weights, mid);
if(days > D) {
minLoad = mid + 1;
}
else {
maxLoad = mid;
}
} return minLoad;
}
}

Capacity To Ship Packages Within D Days LT1011的更多相关文章

  1. Leetcode之二分法专题-1011. 在 D 天内送达包裹的能力(Capacity To Ship Packages Within D Days)

    Leetcode之二分法专题-1011. 在 D 天内送达包裹的能力(Capacity To Ship Packages Within D Days) 传送带上的包裹必须在 D 天内从一个港口运送到另 ...

  2. [Swift]LeetCode1011. 在 D 天内送达包裹的能力 | Capacity To Ship Packages Within D Days

    A conveyor belt has packages that must be shipped from one port to another within D days. The i-th p ...

  3. 128th LeetCode Weekly Contest Capacity To Ship Packages Within D Days

    A conveyor belt has packages that must be shipped from one port to another within D days. The i-th p ...

  4. LeetCode 1011. Capacity To Ship Packages Within D Days

    原题链接在这里:https://leetcode.com/problems/capacity-to-ship-packages-within-d-days/ 题目: A conveyor belt h ...

  5. Leetcode: Capacity To Ship Packages Within D Days

    A conveyor belt has packages that must be shipped from one port to another within D days. The i-th p ...

  6. Capacity To Ship Packages Within D Days

    A conveyor belt has packages that must be shipped from one port to another within D days. The i-th p ...

  7. 【leetcode】1014. Capacity To Ship Packages Within D Days

    题目如下: A conveyor belt has packages that must be shipped from one port to another within D days. The  ...

  8. 【LeetCode】1014. Capacity To Ship Packages Within D Days 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  9. Leetcode 1014. Capacity To Ship Packages Within D Days

    二分搜索 class Solution(object): def shipWithinDays(self, weights, D): """ :type weights: ...

随机推荐

  1. ssh 使用 aws

    使用 PuTTY 从 Windows 连接到 Linux 实例 启动您的实例之后,您可以连接到该实例,然后像使用您面前的计算机一样来使用它. 注意 启动实例后,需要几分钟准备好实例,以便您能连接到实例 ...

  2. 【Scrapy】关于使用Scrapy框架爬虫遇到的问题1

    class testScrapy(scrapy.Spider): name = "testLogs" allowed_domains=["cnblogs.com" ...

  3. oracle锁---原理篇

    在现代的多用户多任务系统中,必然会出现多个用户同时访问共享的某个对象,这个对象可能是表,行,或者内存结构,为了解决多个用户并发性访问带来的数据的安全性,完整性及一致性问题,必须要有一种机制,来使对这些 ...

  4. centos如何查看磁盘剩余空间

    linux系统的Df命令是以磁盘分区为单位查看文件系统,可以加上参数查看磁盘剩余空间信息,命令格式: df -hl 显示格式为: 文件系统 容量 已用 可用 已用% 挂载点 /dev/hda5 487 ...

  5. layui复选框

    效果图 layui复选框,一个主的复选框控制多个从复选框,主复选框和从复选框的颜色不一样 layui复选框的样式,都是在选然后才会有的,所以直接通过css设置就实现不了了.只可以通过js动态设置 ht ...

  6. 如何彻底卸载mysql(xp)

    如何彻底卸载mysql 完整的卸载MySQL 5.x 的方法: 1.控制面板里的增加删除程序内进行删除 2.删除MySQL的安装文件夹C:\Program Files\MySQL,如果备份好,可以直接 ...

  7. TZOJ 2546 Electricity(去掉割点后形成的最大连通图数)

    描述 Blackouts and Dark Nights (also known as ACM++) is a company that provides electricity. The compa ...

  8. f5电源模块损坏

    现象: ssh登录f5后有日志显示 现场确认f5 2槽电源指示灯不亮,且电源线正常.重新开关电源模块,拔插电源线后仍不亮.故确认是电源模块损坏. 处理:直接采购新的电源模块更换即可.f5电源支持热插拔 ...

  9. jquey中json字符串与json的转换(转)

    <!doctype html> <html> <head> <meta charset="utf-8"> <script sr ...

  10. transaction注解分析

    1. Spring事务的基本原理 事务管理是应用系统开发中必不可少的一部分.Spring 为事务管理提供了丰富的功能支持.Spring 事务管理分为编码式和声明式的两种方式.编程式事务指的是通过编码方 ...