LOJ 10189 仓库建设 ——斜率优化dp

题目:https://loj.ac/problem/10189

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define db double
#define ll long long
using namespace std;
const int N=1e6+5;
int n,d[N],p[N],C[N];
ll s[N],c[N],dp[N];
int q[N],he,tl;
int rdn()
{
  int ret=0;bool fx=1;char ch=getchar();
  while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
  while(ch>='0'&&ch<='9') ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
  return fx?ret:-ret;
}
ll Y(int a){return dp[a]+c[a]*d[a]-s[a];}
db slp(int u,int v){return (db)(Y(v)-Y(u))/(d[v]-d[u]);}
int main()
{
  n=rdn();
  for(int i=1;i<=n;i++)
    d[i]=rdn(),p[i]=rdn(),C[i]=rdn();
  for(int i=1;i<=n;i++)
    d[i]=d[n]-d[i];
  for(int i=n;i>=0;i--)
    c[i]+=c[i+1]+p[i],s[i]=s[i+1]+(ll)p[i]*d[i];
  he=1;q[tl=1]=n;dp[n]=C[n];
  for(int i=n-1;i>=0;i--)
    {
      while(he<tl&&slp(q[he],q[he+1])<=c[i+1])he++;
      int j=q[he];
      dp[i]=dp[j]+c[j]*d[j]-s[j]-c[i+1]*d[j]+s[i+1]+C[i];
      while(he<tl&&slp(q[tl-1],q[tl])>=slp(q[tl-1],i))tl--;
      q[++tl]=i;
    }
  printf("%lld
",dp[0]);
  return 0;
}
原文地址:https://www.cnblogs.com/Narh/p/9921600.html