437. 书籍复印

437. 书籍复印

中文English

给定 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
解释: 三个人各复印一本书.

挑战

时间复杂度 O(nk)

注意事项

书籍页数总和小于等于2147483647

输入测试数据 (每行一个参数)如何理解测试数据?

解法1:划分型动态规划,min(max())的解法

class Solution:
    """
    @param pages: an array of integers
    @param k: An integer
    @return: an integer
    """
    """
    大致思路:
    1.min(dp[k][n],max(dp[k-1][j],A[j] + A[j + 1] + ... + A[n]))
    前k-1个抄写员,抄写j本书 和 最后一个抄写员抄写剩下的部分(可能剩下的部分书为0,前面k-1个人可以抄写完毕)
    """
    def copyBooks(self, pages, k):
        # write your code here
        if len(pages) == 0:return 0 

        #如果抄写员个人大于pages,只需要取出所有连续的书中,需要最多时间的那本书即可
        n = len(pages)
        if (k >= n):return max(pages)

        #初始化
        dp = [[sys.maxsize]*(n + 1) for _ in range(k + 1)]
        #0个抄写员,抄写0本需要0时间
        dp[0][0] = 0
        #0个抄写员,抄写大于0本需要正无穷时间

        #n个抄写员,抄写0本,需要0时间
        for i in range(1, k + 1):
            dp[i][0] = 0

        #计算顺序
        #人数
        for i in range(1, k + 1):
            #书本数
            for j in range(1, n + 1):
                dp[i][j] = sys.maxsize

                #给定最后一个人所花费的时间总和,和前k个人所花费的时间和,求最大值
                sum = 0
                #最后一个人所花费时间,从j本书到n本书,A[j] + A[j + 1] + ... + A[n]
                #前k - 1 个人所花费时间,dp[k - 1][j] 前j本书,也可能前k - 1个人完成全部的书
                for z in range(j, -1, -1):#要包含dp[0][0],pages[0]的比较
                    dp[i][j] =  min(dp[i][j], max(dp[i - 1][z], sum))#i是从第一个人开始0开始计算的

                    #因为pages第一本书是从0开始的,所以需要减去1
                    if (z - 1 >= 0):
                        sum += pages[z - 1]

        return dp[k][n]

注:lintcode超时,待优化,时间复杂度O(k*n*n)。

原文地址:https://www.cnblogs.com/yunxintryyoubest/p/13082349.html