对于一个正整数n,给定序列a1~an,求出子序列al,al+1…ar,使得Σai(l<=i<=r)最大
已知|ai|<=10^9 n<=10^6
策略:
先求出前缀和数组sum[i]=Σaj(1<=j<=i)
对于所有右端点为r的子序列,对应的序列和可以表示为
sum[r]-sum[l-1]
l是区间左端点
当r确定的时候,找出一个最小的sum[l-1]即为最大
枚举右端点r,枚举过程中求出最大的sum[r]-sum[l-1],然后跟答案取max
难度升级:我们求出的子序列要求长度必须大于等于给定整数x
策略:思路一样,但是需要改一下l的范围
之前l是属于区间[1,r]
现在是属于区间[1,r-x+1]
难度升级2:我们求出的子序列长度必须小于给定整数x
策略:依然只改l范围
l的范围是[r-x+2,r]
之前可以直接边枚举r边对sum取最小值
现在必须使用单调队列进行限制
难度升级3:现在要求出 Σai(l<=i<=r)/(r-l+1) 最大
也就是平均值最大
PS:ai>=0
策略:
这次我们采用二分答案的做法
首先,对于一个给定的平均值,我们需要完成一个函数,用于检测是否存在平均值大于给定平均值的子区间
为了完成以上目标,我们可以让原序列先全部减去这个平均值x,这样序列就变得有正有负,在这种情况下,只要用先前的策略,求出是否有某个区间的和是大于0的,如果大于等于0,则说明存在
然后我们二分这个给定的均值,就可以找出最大的均值了
对长度进行限制参考上面两种做法
例题:
2021牛客暑期多校训练营4
J-Average
Bob has an n×m matrix W.
This matrix is very special, It’s calculated by two sequences a_{1…n},b_{1…m} Wi,j = ai+bj
Now Bob wants to find a submatrix of W with the largest average value.
Bob doesn’t want the size of submatrix to be too small, so the submatrix you find must satisfy that the width(the first dimension of matrix) of it is at least x and the height(the second dimension of matrix) of it is at least y.
Now you need to calculate the largest average value
题目大意:
给定一个n*m的矩阵W,矩阵上的每一个位置的数字都由两个给出的序列a,b计算得到 Wi,j = ai + bj
对此,我们要求出一个平均值最大的子矩阵,并且这个子矩阵的长(第一维)必须大于x,宽(第二维)必须小于y
ΣWi,j(a<=i<=b , c<=j<=d)/(b-a+1)(d-c+1)
通过数学推导可知,上式可化为a,b两个序列的平均值最大的子序列平均值之和(长度分别大于x和y)
代码:
#include <bits/stdc++.h>
using namespace std;
bool work(const int an[]