bzoj 1096 仓库建设 —— 斜率优化DP
2024-09-07 10:57:56
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1096
设 f[i] 为 i 作为最后一个仓库时前 i 个工厂的答案,最后的答案当然是 f[n];
f[i] = min{ f[j] + ∑(j+1<=k<=i)p[k]*(x[i]-x[k]) + c[i] } , 1<=j<i
令 s[i] = ∑(1<=j<=i)p[j],t[i] = ∑(1<=j<=i)p[j]*x[j]
则 f[i] = min{ f[j] + x[i]*(s[i]-s[j]) - (t[i]-t[j]) + c[i] }
移项,得到 f[j] + t[j] = x[i]*s[j] - x[i]*s[i] + t[i] - c[i] + f[i]
x[i] 单增,s[j] 单增,可以看出是要维护一个下凸包。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef double db;
typedef long long ll;
int const xn=1e6+;
int n,x[xn],p[xn],c[xn],q[xn];
ll s[xn],t[xn],f[xn];
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return f?ret:-ret;
}
db y(int i){return f[i]+t[i];}
db slp(int a,int b){return (y(b)-y(a))/(s[b]-s[a]);}
int main()
{
n=rd();
for(int i=;i<=n;i++)
{
x[i]=rd(),p[i]=rd(),c[i]=rd();
s[i]=s[i-]+p[i]; t[i]=t[i-]+(ll)p[i]*x[i];
}
int hd=,tl=;
for(int i=;i<=n;i++)
{
while(hd<tl&&slp(q[hd],q[hd+])<x[i])hd++;
f[i]=f[q[hd]]+(ll)x[i]*(s[i]-s[q[hd]])-t[i]+t[q[hd]]+c[i];
while(hd<tl&&slp(q[tl-],q[tl])>slp(q[tl-],i))tl--;
q[++tl]=i;
}
printf("%lld\n",f[n]);
return ;
}
最新文章
- I18N 国际化
- SQL Server 【附】创建";商品管理数据库";、";学生选课数据库";的SQL语句
- HDU 4638 Group 树状数组 + 思路
- Delphi Register
- 计算4000000000内的最大f(n)=n值---字符串的问题python实现(五岁以下儿童)
- Android面试题集合
- flask token认证
- spark DataFrame
- (转)flutter 新状态管理方案 Provide (一)-使用
- SCUCTF2018web部分wp
- canvas和图片互转
- matlab中生成随机数的相关知识
- django不返回QuerySets的API
- 树莓派raspberry Pi2 介绍
- vijos 1659 河蟹王国 线段树区间加、区间查询最大值
- kernel 3.2.0 上加入自己的板级文件
- Spring之HandlerInterceptor拦截器
- 什么是Qt Widget?
- 解决Vue方法中setTimeout改变变量的值无效
- 百万级数据库SQL优化大总结