zoukankan      html  css  js  c++  java
  • 牛客 小A与最大子段和(斜率优化dp)

    这道题也是斜率优化的题目,可以用代数法化简,但是本题有个问题是

    直线的斜率不一定递增,所以需要二分查找。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=2e5+20;
    typedef long long ll;
    ll a[N],f[N],q[N],s[N],b[N];
    ll getup(int i,int j){
        return i*b[i]-s[i]-(j*b[j]-s[j]);
    }
    int getdown(int i,int j){
        return i-j;
    }
    int bs(int l,int r,ll val){
        while(l<r){
            int mid=(l+r)/2;
            if(getup(q[mid+1],q[mid])>val*(q[mid+1]-q[mid]))
                l=mid+1;
            else
                r=mid;
        }
        return l;
    }
    int main(){
        int i;
        int n;
        cin>>n;
        for(i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            b[i]=b[i-1]+a[i];
            a[i]*=i;
            s[i]=s[i-1]+a[i];
        }
        ll res=-1e18;
        int tt=0;
        int hh=0;
        for(i=1;i<=n;i++){
            int l=hh,r=tt;
            int ans=bs(l,r,b[i]);
            f[i]=s[i]-s[q[ans]]-q[ans]*(b[i]-b[q[ans]]);
            res=max(res,f[i]);
            while(hh<tt&&getup(q[tt],q[tt-1])*getdown(i,q[tt])<=getup(i,q[tt])*getdown(q[tt],q[tt-1]))
                tt--;
            q[++tt]=i;
        }
        cout<<res<<endl;
    }
    View Code
  • 相关阅读:
    第五周
    第四周
    第三周作业
    第二周编程总结
    编程总结(3)
    编程总结(2)
    编程总结(1)
    第七周作业
    第六周作业
    第五周作业
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12552358.html
Copyright © 2011-2022 走看看