bzoj1096(斜率优化)

来源:互联网 发布:sqlserver时间比较 编辑:程序博客网 时间:2024/05/22 16:59

锯木厂选址复杂版。

注意颠倒一下顺序做即可


#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<cstdlib>using namespace std;typedef long long ll;const int N=1000005;ll read(){ll ans,f=1;char ch;while ((ch=getchar())<'0'||ch>'9') if (ch=='-') f=-1;ans=ch-'0';while ((ch=getchar())>='0'&&ch<='9') ans=ans*10+ch-'0';return ans*f;}ll sum[N],dis[N],x[N],p[N],c[N],f[N],s[N];int n,q[N],head,tail;void init(){n=read();for (int i=1;i<=n;i++) x[i]=read(),p[i]=read(),c[i]=read();for (int i=1;i<=n/2;i++) swap(p[i],p[n-i+1]),swap(c[i],c[n-i+1]);for (int i=1;i<=n;i++) dis[i]=x[n]-x[n-i+1];for (int i=1;i<=n;i++) sum[i]=sum[i-1]+p[i];for (int i=1;i<=n;i++) s[i]=s[i-1]+(sum[i]-sum[i-1])*dis[i];}ll getup(int j,int k){return (f[j]-s[j]+sum[j]*dis[j+1])-   (f[k]-s[k]+sum[k]*dis[k+1]);}ll getdown(int j,int k){return dis[j+1]-dis[k+1];}ll getdp(int i,int j){return f[j]+s[i]-s[j]-dis[j+1]*(sum[i]-sum[j])+c[i+1];}void work(){c[++n]=0;sum[n]=sum[n-1];dis[n]=dis[n-1];s[n]=s[n-1];head=tail=1;q[1]=0;f[0]=c[1];for (int i=1;i<=n-1;i++){while (head<tail &&getup(q[head+1],q[head])<=sum[i]*getdown(q[head+1],q[head])) head++;f[i]=getdp(i,q[head]);while (head<tail && getup(i,q[tail])*getdown(q[tail],q[tail-1])<=getup(q[tail],q[tail-1])*getdown(i,q[tail])) tail--;q[++tail]=i;}printf("%lld",f[n-1]);}int main(){init();work();return 0;}


0 0
原创粉丝点击