动态规划-书籍复印
- 1 描述
- 2 样例
- 2.1 样例 1:
- 2.2 样例 2:
- 3 解题方法
- 3.1 算法解题思路
- 3.2 算法代码实现
该题是lintcode上的算法题,该题的解题思路是依据九章侯老师提供的解题思路去处理的:
https://www.lintcode.com/problem/437/description
1 描述
给定n本书,第i本书有pages[i]页。有k个人来抄这些书。
这些书排成一行,每个人都可以索取连续一段的书。例如,一个抄书人可以连续地将书从第i册复制到第j册,但是他不能复制第1册、第2册和第4册(没有第3册)。
他们在同一时间开始抄书,每抄一页书都要花1分钟。为了让最慢的抄书人能在最早的时间完成书的分配,最好的策略是什么?
请返回最慢抄书人花费的最短时间。
仅限7天:《微博评论系统项目实战》早鸟价¥199
微信加【jiuzhang1104】备注【微博】了解详情&参与拼团
书籍页数总和小于等于2147483647
2 样例
2.1 样例 1:
输入: pages = [3, 2, 4], k = 2
输出: 5
解释: 第一个人复印前两本书, 耗时 5 分钟. 第二个人复印第三本书, 耗时 4 分钟.
2.2 样例 2:
输入: pages = [3, 2, 4], k = 3
输出: 4
解释: 三个人各复印一本书.
3 解题方法
3.1 算法解题思路
该算法处理的核心点就是下面的转移方程
3.2 算法代码实现
public class Solution {
/**
* @param pages: an array of integers
* @param k: An integer
* @return: an integer
*/
public int copyBooks(int[] pages, int k) {
int n = pages.length;
if (n == 0) {
return 0;
}
if (k > n) {
k = n;
}
int[][] f = new int[k + 1][n + 1];
f[0][0] = 0;
for (int i = 1; i <= n; ++i) {
f[0][i] = Integer.MAX_VALUE;
}
//状态转移方程
//f[k][i] = min (j=0...i) {max{f[k-1][j], A[j]+...+A[i-1]}}
for (int m = 1; m <= k; ++m) { // 枚举 k 从 1 到 K
f[m][0] = 0;
for (int i = 1; i <= n; ++i) { // 枚举 书 1 到 n
f[m][i] = Integer.MAX_VALUE;
int sum = 0;
for (int j = i; j >= 0; j--) {
// 枚举之前K-1个人抄了j本书的情况,和剩下的书所时间比较取其大,再刷新当前最小记录
f[m][i] = Math.min(f[m][i], Math.max(f[m - 1][j], sum));
if (j > 0) {
sum += pages[j - 1];
}
}
}
}
return f[k][n];
}
}