zoukankan      html  css  js  c++  java
  • HDU 2993 MAX Average Problem dp斜率优化

    MAX Average Problem

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 5803    Accepted Submission(s): 1433


    Problem Description
    Consider a simple sequence which only contains positive integers as a1, a2 ... an, and a number k. Define ave(i,j) as the average value of the sub sequence ai ... aj, i<=j. Let’s calculate max(ave(i,j)), 1<=i<=j-k+1<=n.
     
    Input
    There multiple test cases in the input, each test case contains two lines.
    The first line has two integers, N and k (k<=N<=10^5).
    The second line has N integers, a1, a2 ... an. All numbers are ranged in [1, 2000].
     
    Output
    For every test case, output one single line contains a real number, which is mentioned in the description, accurate to 0.01.
     
    Sample Input
    10 6 6 4 2 10 3 8 5 9 4 1
     
    Sample Output
    6.50
     
     
    这道题不是普通的斜率优化,详细题解参见:http://blog.sina.com.cn/s/blog_ad1f8960010174el.html
    由于把题目数据范围从10^4提到了5*10^5,我用自己出的数据对拍,网上的标程基本爆掉。
    只有一点要注意,就是不加读入优化绝对TLE。一般O(n)的题都是这样。
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    typedef long double real;
    #define MAXN 510000
    #define max(x,y) ((x)>(y)?(x):(y))
    typedef long long qword;
    int num[MAXN];
    int sum[MAXN];
    int n;
    real f[MAXN];
    real ans=0;
    struct Point
    {
            qword x,y;
    }pl[MAXN];
    int topl=-1;
    qword xmul(Point p1,Point p2,Point p3)
    {
            return (p2.x-p1.x)*(p3.y-p1.y)-(p2.y-p1.y)*(p3.x-p1.x);
    }
    real get_k(Point p1,Point p2)
    {
            return real(p1.y-p2.y)/(p1.x-p2.x);
    }
    inline int getInt(int &ret)
    {
            char ch=getchar();
            ret=0;
            while (ch>'9'||ch<'0')ch=getchar();
            while (1)
            {
                    ret=ret*10+ch-'0';
                    ch=getchar();
                    if (ch>'9'||ch<'0')break;
            }
    }
    
    int main()
    {
            freopen("input.txt","r",stdin);
            int i,j,k;
            while (~scanf("%d%d",&n,&k))
            {
                    Point pp;
                    for (i=1;i<=n;i++)
                    {
                //            scanf("%d",&num[i]);
                            getInt(num[i]);
                            sum[i]=sum[i-1]+num[i];
                    }
                    /*
                    for (i=1;i<=n;i++)
                    {
                            for (j=i-k+1;j>=1;j--)
                            {
                                    ans=max(ans,real(sum[i]-sum[j-1])/(i-j+1));
                            }
                    }*/
                    ans=0;
                    int ptr=-1;
                    int now;
                    Point pi;
                    int head=0;
                    topl=-1;
                    for (i=1;i<=n;i++)
                    {
                            now=i-k;
                            if (now<0)continue;
                            pi.x=i;pi.y=sum[i];
                            pp.x=now;
                            pp.y=sum[now];
                            if (topl<=head)
                            {
                                    pl[++topl]=pp;
                            }else
                            {
                                    while (topl>=head+1&&xmul(pl[topl-1],pl[topl],pp)<=0)
                                    {
                                            topl--;
                                    }
                                    pl[++topl]=pp;
                            }
                            while (ptr==-1||(ptr<topl&&get_k(pl[ptr],pi)<=get_k(pl[ptr+1],pi)))
                            {
                                    ptr++;
                                    head=ptr;
                            }
                            if (ans<get_k(pl[ptr],pi))
                            {
                                    --++i;
                            }
                            ans=max(ans,get_k(pl[ptr],pi));
                    }
                    printf("%.2lf
    ",(double)ans);
            }
            return 0;
    }
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    Markdown基础语法
    Java是什么
    myBatis框架_关于怎么获得多表查询的总记录数
    关于Could not load driverClass ${jdbc.driverClassName}问题解决方案
    java中String与StringBuffer拼接的区别
    部分标签
    基础标签 网页分类
    入坑小开头
    完整版的OpenLDAP搭建全过程
    测试Linux下tcp最大连接数限制
  • 原文地址:https://www.cnblogs.com/mhy12345/p/3770897.html
Copyright © 2011-2022 走看看