Lintcode 437. 书籍复印
给定 n 本书, 第 i 本书的页数为 pages[i]. 现在有 k 个人来复印这些书籍, 而每个人只能复印编号连续的一段的书, 比如一个人可以复印 pages[0], pages[1], pages[2], 但是不可以只复印 pages[0], pages[2], pages[3] 而不复印 pages[1].
所有人复印的速度是一样的, 复印一页需要花费一分钟, 并且所有人同时开始复印. 怎样分配这 k 个人的任务, 使得这 n 本书能够被尽快复印完?
返回完成复印任务最少需要的分钟数.
Code
def copyBooks(self, pages, k):
# write your code here
n = len(pages)
if n == 0:
return 0
if k >= n:#求最少多少个人,分段方式,不超过k人
k = n
dp = [[0]*(n+1) for _ in range(k+1)]
dp[0][0] = 0
for j in range(1, n+1,1):
dp[0][j] = float('inf')#0个人写i本书
for kc in range(1, k+1,1):#kc个人
dp[kc][0]=0#2.人写0本书
for i in range(1, n+1,1):#i本书
dp[kc][i] = float('inf')#因为要求最小值
s = 0
j=i
while j >= 0:
dp[kc][i] = min(dp[kc][i], max(dp[kc-1][j], s))
#kc-1个人最少需要多少时间抄完前j本书
if j > 0:#递减
s =s+ pages[j-1]
j -= 1
return dp[k][n]#k个人最少需要多少时间抄完前n本书
想法
1.求k个人最少需要多少时间抄完前n本书,需要知道k-1个人最少需要多少时间抄完前j本书。
2. dp[kc][i] = min(dp[kc][i], max(dp[kc-1][j], s))
数字之和的最大值,指书籍数目中最小的一个,指时间
max(dp[kc-1][j], s)
3,s指的是最后一个人抄完j至i-1本书的时间,因为所有人复印的速度是一样的, 复印一页需要花费一分钟,至于倒序是因为这是从j至i-1
4. for kc in range(1, k+1,1):#kc个人
dp[kc][0]=0#2.人写0本书
for i in range(1, n+1,1):#i本书
关于这两个循环,一个是决定人,一个决定最后一个人可以写的书本的数目。
5.j循环的作用,作用是累加前pages[j]-pages[i-1]