P1182 数列分段 Section II (Python 题解)

题目地址:P1182 数列分段 Section II - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

该题目所求为每段和最大值最小为多少,即最优解问题,联想到二分做法。

但问题是怎样去二分?即初始边界

由题目想到,如果极端一点,每个数都分一个组或者把所有数都放在一个组,那么最大值就是我们输入的数列中的最大值和数列求和,那么这就是左边界和右边界了。

这样后我们只要写个判断函数,判断是否合适。

对于每一个组来说它可以有任意个数但是又不能没有,所以这里运用一点贪心思想,题目要求最大值,那么按照常规的二分思想,假设我们的mid值为合适的解(即满足题目要求但是可能不是最优的),那么就遍历题目所给的数列并求和,当它大于或等于我们的mid就分个组,并记数。

遍历完之后,判断所记的数与题目所给的分组数是否相同,相同则说明满足题目要求,但是可能还有更优解(比这个值还要小)那我们就将右边界赋值为mid-1,如果大于说明mid太小了,就将左边界赋值为mid+1,如果小于说明mid太大,就将右边界赋值为mid-1

本题基本思路就是这样。

下面是代码

#洛谷P1182 数列分段 Section II
def check(mid):
    ans = 1
    sen = 0
    for i in range(n):
        if sen+d[i] <= mid:
            sen += d[i]
        else:
            sen = d[i]
            ans += 1
    if ans <= m:
        return True # r = mid-1
    else:
        return False
n,m = map(int,input().split())
d = list(map(int,input().split()))
l = max(d)
r = sum(d)
result = 0
while l<=r:
    mid = (l+r)//2
    if check(mid):
        r = mid-1
        result = mid
    else:
        l = mid+1
print(result)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值