书籍复印
题目:
给定 n 本书, 第 i 本书的页数为 pages[i]. 现在有 k 个人来复印这些书籍, 而每个人只能复印编号连续的一段的书, 比如一个人可以复印 pages[0], pages[1], pages[2], 但是不可以只复印 pages[0], pages[2], pages[3] 而不复印 pages[1].
所有人复印的速度是一样的, 复印一页需要花费一分钟, 并且所有人同时开始复印. 怎样分配这 k 个人的任务, 使得这 n 本书能够被尽快复印完?
返回完成复印任务最少需要的分钟数.
样例
样例 1:
输入: pages = [3, 2, 4], k = 2
输出: 5
解释: 第一个人复印前两本书, 耗时 5 分钟. 第二个人复印第三本书, 耗时 4 分钟.
样例 2:
输入: pages = [3, 2, 4], k = 3
输出: 4
解释: 三个人各复印一本书.
public class Solution {
/**
* @param pages: an array of integers
* @param k: An integer
* @return: an integer
*/
public int copyBooks(int[] pages, int k) {
int len = pages.length;
if(len == 0)
return 0;
//数组定义:dp[i][j]表示i个人复印j本书需要的最少时间
int dp[][] = new int[k + 1][len + 1];
//初始化 0个人只能复印0本书 所以书本数不为0时初始化为一个非法值
for(int i = 1; i <= len; i++) {
dp[0][i] = Integer.MAX_VALUE;
}
/**
状态方程: dp[i][j] = min(dp[i][j], max(dp[i - 1][j], sum(j...i)))
max(dp[i - 1][j], sum(j...i)) 表示取k-1个人复印j本书的最少时间以及J + 1到第i本书复印的时间取最大值,
**/
for(int cur = 1; cur <= k; cur++) {
dp[cur][0] = 0;
for(int i = 1; i <= len; i++) {
dp[cur][i] = Integer.MAX_VALUE;
int sum = 0;
for(int j = i; j >= 0; j--) {
dp[cur][i] = Math.min(dp[cur][i], Math.max(dp[cur - 1][j], sum));
if(j > 0) {
sum += pages[j - 1];
}
}
}
}
return dp[k][len];
}
}