其他分享
首页 > 其他分享> > 斜率dp的模板总结

斜率dp的模板总结

作者:互联网

#include<cstdio>
#include<algorithm>
using namespace std;
long long sumt[40005],sum[40005],f[40005],q[40005];
double X(long long x)
{
    return sumt[x];
} 
double Y(long long x)
{
    return (f[x]+sum[x]);
}
double slope(long long a,long long b)
{
    return ((Y(a)-Y(b))/(X(a)-X(b)));
}
struct ben
{
    long long t,r;
}a[40005],b[40005];
long long cmp(const ben &a,const ben &b)
{
    return a.t>b.t;
}
int main()
{
    freopen("nt2011_design.in","r",stdin);
    freopen("nt2011_design.out","w",stdout); 
    long long l=0,r=0;
    long long n,m;
    scanf("%lld%lld",&n,&m);
    for(long long i=1;i<=n;i++)
    {
        scanf("%lld%lld",&a[i].t,&a[i].r);
    }
    sort(a+1,a+n+1,cmp);
    for(long long i=1;i<=n;i++)
    {
        if(a[i].t==a[i+1].t)
        {
            a[i+1].r+=a[i].r;
            a[i].r=0;
        }
    }
    long long cnt=0;
    for(long long i=1;i<=n;i++)
    {
        if(a[i].r!=0)
        {
            b[++cnt]=a[i];
        }
    }
    long long maxt=b[1].t;
    b[cnt+1].t=0;
    b[cnt+1].r=0;
    cnt++;
    for(long long i=1;i<=cnt;i++)
    {
        b[i].t=maxt-b[i].t;
        sumt[i]=sumt[i-1]+b[i].r;
        sum[i]=sum[i-1]+b[i].t*b[i].r;
    }
    for(long long i=1;i<=cnt;i++)
    {
        while(l<r&&slope(q[l+1],q[l])<b[i].t)l++;
        f[i]=f[q[l]]+b[i].t*(sumt[i]-sumt[q[l]])-(sum[i]-sum[q[l]]);
        if(i!=cnt)f[i]+=m;
        while(l<r&&slope(i,q[r-1])<slope(q[r-1],q[r]))r--;
        q[++r]=i;
    }
    printf("%lld\n",f[cnt]);
    return 0; 
}

标签:return,double,nt2011,long,斜率,40005,dp,ben,模板
来源: https://www.cnblogs.com/ShineEternal/p/11333869.html