基本运算之二分

二分的两种用法:

  1. 求边界
  2. 将最优解问题转换为判定问题

三分:

  • 用来求函数极值

## AcWing 102. 最佳牛围栏

用到了二分的第二种用法,前缀和,和平均值的数学知识

题目可以抽象为对给定数目个数为N的序列,在所有长度大于等于F的子序列中,求出最大平均值

  1. 将最优解问题转换为二分的判定问题。 为什么可以转换?原因在于在所有可能的平均值(平均值按升序排列)中,任取x0,如果存在子序列的平均值大于x0,则答案肯定在x0的左侧;如果都小于x0,那么答案肯定在右侧;
  2. 用非负性判断是否存在平均值大于x0的子序列。 对于平均值问题,可以将原序列减去x0得到新的序列,如果该序列的某一子序列和大于0,说明该子序列的平均值大于x0;反之则小于。新序列的子序列和用前缀和来计算
  3. 双指针遍历前缀和。 建立两个指针i、j, j比i大F。用minv记录[0……i]的最小前缀和,那么sum[j] - minv就是以j结尾的最大子序列和。我们要判断所有以j结尾的子序列和是否大于0,只要判断sum[j] - minv是否大于0即可。

特殊排列

用分治或递推的思想,规模更小的问题:i - 1个元素的特殊排列已知。将每个点看成一个线段,对于第i个数而言,小于i的数为单调递减的线段,大于i的数为单调递增的线段。对于极小值点,一定有极小值点左边的线段单调递减或不存在,右边的线段单调递增或不存在,因此可以用二分求出极小值点左边第一个单调递减的线段。

赶牛入圈

考察点:二分、前缀、离散化

首先想到的做法:枚举所有边长的正方形,看其能否包含至少C个单位。

这种问题很明显要用到前缀和。我们枚举正方形的每个位置(右上角的位置),如果提前求出了前缀和,就可以用O(1)的时间复杂度求出包含的单位数。

如果暴力枚举,时间复杂度为10^12,肯定会超时。因此可以用二分法去枚举边长,转换为二分判定问题。

因为点的下标在1 ~ 10000 之间,如果在判定时暴力枚举每个正方形的位置,还是会超时。再次观察到点的个数只有500个,因此我们可以尝试离散化的思路。

我们可以把这500个点的x、y坐标离散化,建立一个包含这500个点的新的坐标系。500个点的x、y坐标最多有1000个数,因此判定的时间复杂度为10^6。

这里又引发了一个问题:正方形的最佳位置(包含最多单位的位置)有没有可能在离散化后的坐标系的两个点之间?其实是不可能的。如果真的存在这种位置,不妨设(1.5, 2.5),那么此时正方形的最右边和最上边是没有点的。此时我沿x轴移动到1位置,沿y轴移动到2位置,在不会损失原单位的同时,可能还会包含进新的单位。我们甚至可以一直移动直到最右边和最上边有点,而有点的位置就位于离散化后的坐标系上整数坐标的位置。所以(1.5, 2.5)一定不是最佳位置。

事实上,这也是使用离散化的前提条件。离散化的目的就是为了避免枚举“没用”的点来降低时间复杂度。但是我们在实际做题的时候是很难立刻想出来的,因此根据题目特征想到一个方法,再去验证它的合理性是很好的一种选择。

需要注意的是,在离散化后的新坐标系中,点与点之间距离和其实际距离不同。我们枚举正方形的所有可能位置,根据实际距离,判断出第一个不在范围内的x1和y1,之后根据前缀和就能求出正方形在该位置包含的单位数。

整数小拼接

一。可以通过双重遍历找到所有的数对。数对的两个数交换位置拼接的数不同。

1.可以把原序列按升序排列,找到所有符合要求的数对;再按降序排列,找到所有的数对。这样就能遍历出所有拼接的数。

也可以只升序,然后二分整个数组。
2.升序排列的原序列,内部遍历的数对满足大小单调递增。可以用二分法。降序单调递减,同理。
3.如何拼接?用sstream会超时。想其它办法。
1)用string数组储存。每个数相当于string。要用到:string的比较。string比较的时间复杂度未知。
2)用PII记录出每个数的size
3)预处理出每个数的所有倍数

二。将数组按升序排列,顺序枚举每个数,将其作为数对的第二个数。二分,求出与其拼接 <= k的最后一个数的下标即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值