书籍复印

书籍复印

题目:
给定 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];
    }
}
原文地址:https://www.cnblogs.com/katoMegumi/p/14035091.html