挺有意思的小题目
题目描述
把一个包含n个正整数的序列划分成m个连续的子序列(每个正整数恰好属于一个序列)。设第i个序列的各个数之和为S(i),你的任务是让所有S(i)的最大值尽量小。
例如序列1 2 3 2 5 4 划分成3个序列的最优方案为 1 2 3 | 2 5 | 4,其中S(1)、S(2)、S(3)分别为6、7、4,最大值是7;
如果划分成1 2 | 3 2 | 5 4,则最大值为9,不如刚才的好。n<=10^6,所有数之和不超过10 ^ 9。
思路
“最大值尽量小”是一种很常见的优化目标。我们考虑一个新的问题:能否把输入序列划分成m个连续的子序列,使得所有S(i)均不超过x?我们把这个问题的答案用谓词P(x)表示,则让P(x)为真的最小x就是原题的答案。
那么x该如何取值呢?
我的思路是从小递增,找到合适的,而最小的那个是数组之和除以划分的子序列的个数。例如1 2 3 2 5 4,那么x就由6开始。
代码
numbers=[1,2,3,2,5,4,4]
m=int(input())
nums=sum(numbers)
if nums%m!=0:
a=nums//m+1
else:
a=nums//m
while True:
b=0
for i in range(m-1):
n=0
d=b
for i in range(d,len(numbers)):
temp=sum(numbers[b:i+1])
if temp>a:
b=i
break
elif temp==a:
b=i+1
break
if sum(numbers[b:])<=a:
print(a)
break
else:
a+=1
有不足之处欢迎在评论区留言~~~