Best Cow Fences
学习这题
题目要求去划分n个点,要求使得在一段长度不小于L的子区间中每个点得到的平均值最大,并输出这个最大的平均值。
首先这题,模拟、枚举的想法肯定是不行的。
题目只要我求最大的平均值,意味着对平均值可以是一个单调递增的函数,函数值为 是否存在 一个子区间使得 自变量 平均值存在。
二分答案+判定:
1、二分平均值 average
2、将所有的点减去 average
3、对区间求前缀和。
4、枚举每个长度为 L 的子区间,减去当前最小值,这时长度至少为 L(并且可能大于,这是满足要求的)。设:这次扫描得到的最大的 和 为 ans
5、
(1)、如果 这次找到的 ans 是小于0的,那么意味着,当前的 average 太大了,以至于没有任何一个子区间的平均值是能够达到当前的 average ,即:不存在满足当前 average 的情况。
(2)、否则 ans 大于等于0,就说明:有能够达到当前 average 的子区间方案,average 是可能是答案的。
6、对于 ans<0,则要变小 average,那么二分的区间就应往小的方向取;对于 ans>=0,则还可以变大 average 去尝试,区间往大的方向取。
考虑为什么二分是正确的:
1、函数是单调的,这是显然的
考虑为什么要用二分答案做:
1、原问题正向求解非常复杂,很难做;而将问题转换为判定后,求解往往会变得简单很多,求解就变成了 验证。
考虑标程的实现细节
min_val = min( min_val , sum[i-L] );
ans = max( ans , sum[i]-min_val );
1、这里先更新最小值,就可以把区间长度恰好为 L 的情况考虑进去。
2、因为这里区间长度最短为 L,所以直接从 i-L 开始更新
3、对于以 i 结尾的前缀和,减去前面最小的就可以得到 最大的区间和
4、为什么选择先全部减去 average ?
减完之后加起来,总和的正负就表示了是否可以,免去了全部加起来除再判断时的时耗和精度误差;免去了 全部加起来然后于 average*n 比较的麻烦和乘法(虽然我觉得乘一下其实没什么,但要是精度误差了就GG了啊)

本文探讨了一种使用二分法解决特定类型优化问题的方法,即在给定长度下寻找一组数值中最大平均值的过程。通过将原始问题转化为判定问题,利用二分搜索确定目标平均值,有效避免了复杂度高的枚举或模拟方法。

500

被折叠的 条评论
为什么被折叠?



