2021牛客暑期多校训练营4Average(前缀和+浮点二分)

思路:
对于矩阵 W W W,给他硬二维构造肯定是不行,空间太大,那么我们肯定就要寻找其中的规律。

我们假定存在一个 h h h行, k k k列的子矩阵使得答案最大,我们可以发现每个 a i a_i ai只与第i行有关,而每个 b i b_i bi
只与第i列有关,在模拟一下平均值:

( a 1 + a 2 + a 3 … … + a h ) ∗ k + ( b 1 + b 2 + … … + b k ) ∗ h h ∗ k \frac{(a_1+a_2+a_3……+a_h)*k+(b_1+b_2+……+b_k)*h}{h*k} hk(a1+a2+a3+ah)k+(b1+b2++bk)h

( a 1 + a 2 + a 3 … … + a h ) h \frac{(a_1+a_2+a_3……+a_h)}{h} h(a1+a2+a3+ah) + + + ( b 1 + b 2 + … … + b k ) k \frac{(b_1+b_2+……+b_k)}{k} k(b1+b2++bk)

那么我们就可以根据规律来做题啦,我们只需要找到数组a和数组b最大的平均值相加即可。
怎么找呢(赛场愣是不会)
当然我们可以二分答案,利用前缀和来维护,每次都让数组里的元素减去二分答案,在依次判断,如果存在大于等于 0 0 0的情况即为可行。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<map>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<sstream>
#include<queue>
#define fr for
#define pi 3.1415926535
#define me(a,b,c) memset(a,b,sizeof c)
#define cut cout
#define eps 0.00000001
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
typedef pair<int, int> pii;
const int N = 1e6 + 10;
double a[N];
double b[N];
double sum[N];
bool check(double f[], double s,int len,int re) {
	
	sum[0] = 0;
	for (int i = 1; i <= len; i++)sum[i] = sum[i - 1] + f[i] - s;
	double p = 0x3f3f3f3f;
	for (int i = re; i <= len; i++) {
	
		p = min(p, sum[i - re]);//保证区间长度至少为re
		
		if (sum[i] - p >= 0)return true;

	}
	return false;

}
int main() {
	int n, m, x, y;
	cin >> n >> m >> x >> y;
	fr(int i = 1; i <= n; i++)cin >> a[i];
	fr(int i = 1; i <= m; i++)cin >> b[i];
	double l = 0, r = 1e5 + 10;
	while (r - l > eps) {
		double mid = (l + r) / 2;
		if (check(a,mid,n,x))l = mid;
		else r = mid;
	}
	double ans = l;
	l = 0, r = 1e5 + 10;
	while (r - l > eps)
	{
		double mid = (l + r) / 2;
		if (check(b, mid,m,y))l = mid;
		else r = mid;
	}
	ans += l;
	printf("%.10lf\n", ans);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值