斜率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;
}
作者&出处:ShineEternal
本文阅读完毕欢迎到此留言:link
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利.
你看地这么津津有味,不点个赞再走吗QAQ