Average

题目链接

  • 二分答案转化为判定,这样我们就只关心最大的和是否大于0,而不关心除以区间长度的干扰了
  • 赛场上阴差阳错地写对了斜率优化,但是想不明白原理,几经周折查找资料,终于明白了:
  • 弹出队头决策的确会导致当前解未必最优,但一定不会干扰全局最优解;如果需要查找当前最优解,则需要二分下凸壳
  • 在DP的斜率优化中,是确定了斜率,自下而上用直线扫描,求最小截距的;本题则是确定了点,求最大斜率
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int a[100005];
long long sum[100005];
double ans;
deque<int>q;
double k(int j,int i)
{
	return 1.0*(sum[j]-sum[i])/(j-i);
}
void add(int id)
{
	while(q.size()>1)
	{
		int i=q.back();
		q.pop_back();
		int j=q.back();
		if(k(id,i)>k(i,j))
		{
			q.push_back(i);
			break;
		}
	}
	q.push_back(id);
}
void calc(int n,int x)
{
	double res=0;
	q.clear();
	if(x==1)
	{
		add(0);
	}
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		sum[i]=sum[i-1]+a[i];
		while(q.size()>1)
		{
			int j=q.front();
			q.pop_front();
			int l=q.front();
			if(k(i,j)>k(i,l))
			{
				q.push_front(j);
				break;
			}
		}
		if(!q.empty())
		{
			res=max(res,k(i,q.front()));
		}
		if(i-x+1>=0)
		{
			add(i-x+1);
		}
	}
	ans+=res;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n,m,x,y;
	cin>>n>>m>>x>>y;
	calc(n,x);
	calc(m,y);
	cout<<fixed<<setprecision(10)<<ans<<endl;
	return 0;
}
posted @ 2024-10-04 18:31  D06  阅读(3)  评论(0编辑  收藏  举报