好久没有更新我的博客了,最近开始按照老师的要求,每周刷一些算法题,本周主要是练习分治法,做的算法题也是老师建议的题目。
虽然老师讲了好几节课,但我依旧对分治法半懂不懂,我对于它的理解是,找同一个算法过程去循环处理所有的数据,如果有比较懂的同学,欢迎留言!
以下是题目:(不懂英文的同学没有关系,我下面的代码里面有详细的注释)
'''
Monthly Expense
有一个农民,还剩 money 元 [1,10000]
N days,[1,10000]
分为 M 个阶段,[1,N], 阶段称为 fajomonths,必须是连续的天数,至少1天
目的:求出 fajomonths 中的最大值的最小值
'''
import math
# 输入
N = 7
M = 5
day_expense = [100,400,300,100,500,101,400]
# 预期输出 500
# 寻找所有天中的最大花销作为 max(fajomonths) 的最小值,所有天的花销相加作为 max(fajomonths) 的最大值
high = 0
low = 0
for i in range(N):
high = high + day_expense[i]
if low < day_expense[i]:
low = day_expense[i]
# 从连续天数的花销逐个加起,如果花销之和小于当前暂定的 max(fajomonths) ,则归为一个 fajomonths
temp_fajomonths = []
max_sum = 0
# day_expense = [100,400,300,100,500,101,400]
while low < high:
# 暂定的 max(fajomonths)
mid = math.floor((high + low) / 2)
temp_fajomonths = []
sum = 0
max_sum = 0
for j in range(0, N):
if sum + day_expense[j] > mid:
temp_fajomonths.append(sum)
if max_sum < sum:
max_sum = sum
sum = day_expense[j]
# day_expense = [100,400,300,100,500,101,400]
else:
sum = sum + day_expense[j]
if j == (N-1):
temp_fajomonths.append(sum)
if len(temp_fajomonths) > M:
low = mid + 1
break
# day_expense = [100,400,300,100,500,101,400]
# 如果最后分出的 fajomonths 的个数 > M, 则将 max(fajomonths) 的待选值变大,反之变小,
# 由于 max(fajomonths) 有最大值和最小值,所以此处可以采用二分法
if len(temp_fajomonths) < M:
high = mid - 1
elif len(temp_fajomonths) == M:
break
print("fajomonths 中的最大值的最小值是 ", max_sum)
for k in range(len(temp_fajomonths)):
print(temp_fajomonths[k])
运行结果: