zoukankan      html  css  js  c++  java
  • 【斜率优化】Average

    [UVa1451]Average

    算法竞赛入门经典第8章8-9 ( P243 )

    题目大意:给定一个长度为N的01串,选择一个长度至少为L的连续子串,使序列平均值最大 (N<=100001)

    题目分析:预处理前缀和的方法是O(N^2)的时间复杂度。

          那么,设x轴表示下标,y轴表示1的个数,那么连接两个点,构成一条线段。

         对于一条平行于y轴的线,显然,在某些区间内,对于这样的三个点,我们考虑中间那个点的价值:

     

        假设取A区间的一个点,那么显然,最上面的点与选出的点的斜率最大。

        取B区间的一个点,那么最下面的点与选出的点斜率最大。

        取C区间的一个点,那么最上面或者最下面之一肯定比中间的点斜率大。

        由此证明:我们如果遇到这样上突的形状,那么凸点一定可以删除。

        那么对于新加进来的一个点,因为它只会改变从上到下的凸性,所以我们要从栈顶删除(当叉积>=0时删除)。

        i斜率最大的是下凹线的切点,切点前的点不优所以要删除。

        所以我们要维护双端队列。

    代码:

     

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    inline int read(){
    	int x=0,f=1;char c=getchar();
    	for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    	for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    	return x*f;
    }
    
    const int MAXN=100001;
    int Sum[MAXN+1];
    int T,N,Len; char str[MAXN+1];
    int Que[MAXN+1];
    
    int Xc(int x1,int x2,int x3,int x4){
    	return (Sum[x2]-Sum[x1-1])*(x4-x3+1)-(Sum[x4]-Sum[x3-1])*(x2-x1+1);
    }
    
    int main(){
        T=read();
        while(T--){
        	N=read(); Len=read();
    		scanf("%s",str+1);
    		int ansL=1,ansR=N;
    		Sum[0]=0;
    		for(int i=1;i<=N;i++) Sum[i]=Sum[i-1]+(str[i]-'0'); 
    		int L=0,R=0;
    		for(int p=Len;p<=N;p++){
    			while(R-L>1 && Xc(Que[R-2],p-Len,Que[R-1],p-Len)>=0)  R--;
    			Que[R++]=p-Len+1;
    			while(R-L>1 && Xc(Que[L],p,Que[L+1],p)<=0) L++;
    			int rec=Xc(Que[L],p,ansL,ansR);
    			if(rec>0||(rec==0&&p-Que[L]+1<ansR-ansL+1)) ansR=p,ansL=Que[L];
    		}
    		printf("%d %d
    ",ansL,ansR);
    	}
    }

     

  • 相关阅读:
    C# 打印PPT幻灯片
    Java 创建/识别条形码、二维码
    Java 添加Word文本框
    Java 复制PPT幻灯片
    C# 读取Word内容控件
    Java 操作Word书签(三):用文本、图片、表格替换书签
    Java 操作Word书签(二):添加文本、图片、表格到书签内容
    C#/Java 动态生成电子发票
    C# 复制Excel单元格格式
    Java 操作Word书签(一):添加、删除、读取书签
  • 原文地址:https://www.cnblogs.com/wxjor/p/7521850.html
Copyright © 2011-2022 走看看