uva 1451 平均值

Posted jack_yyc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uva 1451 平均值相关的知识,希望对你有一定的参考价值。

题目大意:

一个01串,求一段长度至少为L的区间使这个区间的平均值最大

思路:

因为是一个01串,所以我们可以把串内的点都当做点来处理

每个点的横坐标为它的位置,而纵坐标则为它的前缀和

这样这个串就变为了一个阶梯式的图像

如果点p在线段AB或BC上,取点i

 

如果点p在点C上方,取点k

所以点j并没有啥用,我们可以把它删掉了

我们可以枚举每个结尾点

根据上面的结论我们可以删除距离结尾点l外所有上凸点留下一个凸包

对于这个我们可以使用单调队列来实现

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<vector>
#define inf 2147483611
#define ll long long
#define MAXN 101010
#define MOD 
using namespace std;
inline int read()
{
    int x=0,f=1;
    char ch;ch=getchar();
    while(!isdigit(ch)) {if(ch==\'-\') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-\'0\';ch=getchar();}
    return x*f;
} 
int n,l,T;
int q[MAXN],s[MAXN],head,tail;
char x;
int cmp(int x1,int x2,int x3,int x4) {return (s[x2]-s[x1])*(x4-x3)-(s[x4]-s[x3])*(x2-x1);}
int main()
{
    T=read();
    while(T--)
    {
        head=tail=0;
        n=read(),l=read();
        for(int i=1;i<=n;i++)
        {
            x=getchar();
            s[i]=s[i-1]+x-\'0\';
        }
        int al=0,ar=l;
        for(int i=l;i<=n;i++)
        {
            while(head<tail-1&&cmp(i-l,q[tail-1],i-l,q[tail-2])<0) tail--;//当前队尾不需要 
            q[tail++]=i-l;
            while(head<tail-1&&cmp(q[head+1],i,q[head],i)>=0) head++;//当前队首不需要 
            if(cmp(q[head],i,al,ar)>0||(cmp(q[head],i,al,ar)==0&&(i-q[head]<ar-al))) al=q[head],ar=i;//斜率优于答案或斜率相同长度更短 
        }
        printf("%d %d\\n",al+1,ar);
    }
}
View Code

 

以上是关于uva 1451 平均值的主要内容,如果未能解决你的问题,请参考以下文章

uva 1451 数形结合

UVa 1451 Average -斜率优化

uva 1451(树形结合)

UVa1451 Average (数形结合,斜率优化)

UVA 1451Average

UVA1451 Average