zoukankan      html  css  js  c++  java
  • 【解题报告】洛谷P1419 寻找段落

    【解题报告】洛谷P1419 寻找段落

    题目链接

    https://www.luogu.com.cn/problem/P1419

    思路

    这道题目我们首先可以想暴力,我们暴力的时候记录一个前缀和

    时间复杂度 (O(n^2))

    然后我们考虑优化

    我们要找到的是一个最大的平均区间,我们发现,区间长度越小,实际上,得到最大的平均值越大的概率越高,所以我们可以设置一个时间,然后在快要超时的时候直接退出,返回一个暂时的最优解,虽然时间复杂度没改变,还是能通过这一道题目

    但是我们当然要正统方法

    通过前面的分析可以知道,我们可以二分一个区间的平均值,然后判断这个平均值能不能达到,如果可以达到的话则试更大的平均值,反之,试更小的平均值

    然后二分之内的判断函数实际上就是要找是否存在一个序列,使得这个序列的和大于 (0)

    我们可以使用单调队列来维护是否存在这样一个连续的序列

    总共的时间复杂度 (O(nlogn))

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <string>
    #include <cstring>
    #include <ctime>
    using namespace std;
    const int maxn=100005;
    int s,t;
    int n;
    double a[maxn],b[maxn];
    double mx=-1e9;
    double ans;
    bool check(double x)
    {
    	for(int i=1;i<=n;i++)
    	b[i]=b[i-1]+1.0*a[i]-x;
    	int head=1,tail=0;
    	int q[maxn];
    	for(int i=s,j=0;i<=n;i++,j++)
    	{
    		while(head<=tail&&b[q[tail]]>b[j]) tail--;
    		q[++tail]=j;
    		while(head<=tail&&i-q[head]>t) head++; 
    		if(b[i]-b[q[head]]>0.00001) return true;
    	}
    	return false;
    }
    int main()
    {
    	cin>>n;
    	cin>>s>>t;
    	for(int i=1;i<=n;i++)
    	{
    		cin>>a[i];
    		b[i]=b[i-1]+a[i];
    		mx=max(mx,1.0*a[i]);
    	}
    	double l=-10000,r=10000;
    	while(l<=r-0.00001)
    	{
    		double mid=(l+r)/2.0;
    		if(check(mid))
    		l=mid,ans=l;
    		else
    		r=mid;
    	}
    	printf("%.3lf
    ",ans);
    	return 0;
    }
    
    本博文为wweiyi原创,若想转载请联系作者,qq:2844938982
  • 相关阅读:
    算术操作、张量转换、矩阵运算、归约计算
    CNN与RNN
    基本使用与常用函数
    RNN与LSTM
    CNN训练算法与正则化
    CNN的层级结构
    激活函数
    反向传播与参数更新
    Pipline
    模型存储
  • 原文地址:https://www.cnblogs.com/wweiyi2004/p/15400208.html
Copyright © 2011-2022 走看看