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. 第八篇:Jmeter的分布式测试

    一: 由于Jmeter本身的瓶颈,当模拟数以千计的用户并发的时候,使用单台机器会有些力不从心,甚至还会引起Java内存溢出的错误,要解决这个问题,就要使用分布式测试,运行多台机器,也就是所谓的Agen ...

  2. python+selenium的环境配置

    以前写过关于python和selenium加myeclipse的环境配置,但是myeclipse启动时过于费时,虽然myeclipse有很好的提示功能,但是作为初学者,我还是直接用python的idl ...

  3. 求值器本质--eval&apply

    最近跟着(How to Write a (Lisp) Interpreter (in Python))使用python实现了一个简易的scheme解释器.不得不说使用python这类动态语言实现不要太 ...

  4. Windows Server2012 R2 安装.NET Framework 3.5失败解决方法

    转载:https://blog.csdn.net/F12138_/article/details/80220698 显示需要指定备用路径,但我没有指定 然后就出现了的失败T T! 由于我无法访问安装盘 ...

  5. Oracle中Null与空字符串' '的区别

    含义解释: 问:什么是NULL? 答:在我们不知道具体有什么数据的时候,也即未知,可以用NULL,我们称它为空,ORACLE中,含有空值的表列长度为零. ORACLE允许任何一种数据类型的字段为空,除 ...

  6. 全国绿色计算大赛 模拟赛第一阶段(C++)第1关:求和

    挑战任务 这次“绿盟杯”大赛,小明作为参赛选手在练习的时候遇到一个问题,他要对一个范围的两个数进行数位的累加,例如有两个数 15,19 则 他们的数位和应该为:1+5+1+6+1+7+1+8+1+9, ...

  7. XMPP openfire Smack 即时通讯

    重新整理下这篇文章. 这篇文章的主要任务是使用AndroidStudio,通过Openfire,利用XMPP协议完成一个可以即时通讯.拥有好友系统的聊天软件. 一.服务器配置与相关库 理论不多说,只谈 ...

  8. f5冗余BIG-IP系统的安装

    1.设备服务群集 •一个系列的BIG-Ips彼此互相支持DSC •每一台BIG-IP 自己生成一个Device Object •不同设备的信息 •建立信任证书 •在local device上设置Dev ...

  9. 《基于Nginx的中间件架构》学习笔记---1.环境配置

    一.环境调试确认 (四项确认) 1.确认系统网络 ping www.baidu.com 2.确认yum可用 yum list|grep gcc 3.确认关闭iptables规则 iptables -L ...

  10. centos7下的FastDFS5.09的安装与使用

    FastDFS是一款开源的轻量级分布式文件系统,纯C实现,支持Linux.FreeBSD等Unix系统. 类google FS,不是通用的文件系统,只能通过专有API访问. FastDFS服务端有两种 ...