zoukankan      html  css  js  c++  java
  • CodeForces

    Limak is an old brown bear. He often goes bowling with his friends. Today he feels really good and tries to beat his own record!

    For rolling a ball one gets a score — an integer (maybe negative) number of points. Score for the i-th roll is multiplied by i and scores are summed up. So, for k rolls with scores s1, s2, ..., sk, the total score is . The total score is 0 if there were no rolls.

    Limak made n rolls and got score ai for the i-th of them. He wants to maximize his total score and he came up with an interesting idea. He can say that some first rolls were only a warm-up, and that he wasn't focused during the last rolls. More formally, he can cancel any prefix and any suffix of the sequence a1, a2, ..., an. It is allowed to cancel all rolls, or to cancel none of them.

    The total score is calculated as if there were only non-canceled rolls. So, the first non-canceled roll has score multiplied by 1, the second one has score multiplied by 2, and so on, till the last non-canceled roll.

    What maximum total score can Limak get?

    Input

    The first line contains a single integer n (1 ≤ n ≤ 2·105) — the total number of rolls made by Limak.

    The second line contains n integers a1, a2, ..., an (|ai| ≤ 107) — scores for Limak's rolls.

    Output

    Print the maximum possible total score after cancelling rolls.

    Examples

    Input
    6
    5 -1000 1 -3 7 -8
    Output
    16
    Input
    5
    1000 1000 1001 1000 1000
    Output
    15003
    Input
    3
    -60 -70 -80
    Output
    0

    题意:给定一段数列,现在叫你取其中一段,第一位*1,第二位*2...求最大。

    思路:设前缀和和是sum[n]=a[1]+a[2]+...a[n],原先的dp[n]=a[1]*1+a[2]*2+a[3]*3+..a[n]*n;

               那么现在的max[i]=max:dp[i]-dp[j]-(sum[i]-sum[j])*j; =-sum[i]*j+j*sum[j]-dp[j]+dp[j] 

               显然可以斜率优化,由于K=sum[i]并不是单调递增的,所以我们维护凸包不能弹出队首,而需要二分。

    BZOJ2726一样,就补多说了。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=200010;
    ll s[maxn],dp[maxn],q[maxn],top,ans;
    ll Y(int i){ return s[i]*i-dp[i];}
    ll g(int i,int j){ return dp[i]-dp[j]-j*(s[i]-s[j]); }
    int main()
    {
        int N,i,j;
        scanf("%d",&N);
        for(i=1;i<=N;i++){
            scanf("%I64d",&s[i]);
            dp[i]=dp[i-1]+s[i]*i; 
            s[i]+=s[i-1]; 
            ans=max(ans,dp[i]);
        }
        for(i=1;i<=N;i++){
            int L=0,R=top-1,Mid,t=top;
            while(L<=R){
                Mid=(L+R)>>1;
                if(g(i,q[Mid])>=g(i,q[Mid+1])) t=Mid,R=Mid-1;
                else L=Mid+1;//或者用斜率二分 
            }
            ans=max(ans,g(i,q[t]));
            while(top&&(Y(i)-Y(q[top]))*(q[top]-q[top-1])>(Y(q[top])-Y(q[top-1]))*(i-q[top])) top--;
            q[++top]=i;
        }
        printf("%I64d
    ",ans);
        return 0;
    }
  • 相关阅读:
    不打无准备之仗,最全868道Java面试题及答案
    准备两个月,面试五分钟,Java岗面试为何越来越难?
    2020JAVA面试必备的26个关键知识点,刷完大厂随便跳
    2020年最全java面试真题解析(980道),你没见过的面试题都在这
    java大厂面试200+(含答案):基础+缓存+网络+分布式....
    判断js中的数据类型的几种方法
    JPG、PNG、GIF、SVG 等格式图片区别
    js闭包
    什么是 js 变量提升 (Javascript Hoisting)
    js函数声明和函数表达式的区别
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9246586.html
Copyright © 2011-2022 走看看