这里只简要的记录下自己的想法。
先看简单情况:
对于给定的一个长度为N的正整数数列Ai,现要将其分成连续的若干段,并且每段和不超过M(可以等于M),问最少能将其分成多少段使得满足要求。
详细题目在洛谷里,link1。
这题可以直接用贪心处理,从头遍历到尾,维持一个sum,每当sum超过M时就新起一段,sum归零。
重点在第二种情况。
对于给定的一个长度为N的正整数数列 A1~N ,现要将其分成 M(M≤N)段,并要求每段连续,且每段和的最大值最小。
详细题目在洛谷里,link2。
这题是使用贪心+二分。
使用二分法,将第二种情况化为第一种简单情况,申请一个x来代替第一种情况的M,x如何获得呢?
可以先遍历一遍数组,拿到一个最大的元素left,显然不可能有比这更小的最大值了(因为他已经是单个元素中的最大了,如果还小就不满足<最大>这个条件了),同时拿到所有元素之和的值right,显然不可能有比这更大的最大值了,那么x的取值范围就在[left~right]
。
然后就可以开始二分操作了,取x=(left+rihgt)/2,再利用第一题的函数
判断
对于此正整数数列Ai,将其分成连续的若干段,并且每段和不超过x,求最少能分为多少段,那么就求出一个最少段数len。如果len大于M,那就说明x不满足要求,无法分成M段,x应当被增大,取值范围将变成[x+1,right],如果len小于M,就说明产生了浪费,题目明明可以给你分M段,却只分了不到m段,最大值一定还能缩小,x应当减小,取值范围是[left,x-1]。(因为根据题意很明显,当m增大时,每段和的最大值会递减,而当m减小时,每段和的最大值会递增)
然后就是进一步循环,直到left>right,此时的left(如果是left先移)就是最小的每段和最大值。(注意并不是x,x并不是一个真实存在于数组中的元素,只是一个用于二分的值)