P2120 [ZJOI2007]仓库建设 斜率优化dp
好题,这题是我理解的第一道斜率优化dp,自然要写一发题解。首先我们要写出普通的表达式,然后先用前缀和优化。然后呢?我们观察发现,x【i】是递增,而我们发现的斜率也是需要是递增的,然后就维护一个单调递增就行了。
放一个证明题解。
设f[i]表示在i点建仓库的最小费用,易得方程:f[i]=min(f[j]+(x[i]-x[j+1])*p[j+1]+(x[i]-x[j+1])*p[j+2]...) =min(f[j]+c[i]+x[i]*(p[j+1..i])-(x[j+1]*p[j+1]+...+x[i]*p[i]))
设s[i]=p[1]+p[2]+..p[i],ss[i]=x[1]*p[1]+...x[i]*p[i]
f[i]=f[j]+c[i]+x[i]*(s[i]-s[j])-(ss[i]-ss[j])
设j<k即s[j]<s[k],当取k更优时满足:
f[j]+x[i]*(s[i]-s[j])+ss[j]>f[k]+x[i]*(s[i]-s[k])+ss[k]
x[i]>(f[k]-f[j]+ss[k]-ss[j])/(s[k]-s[j])
设x<y<z,cale(i,j)表示i、j间的斜率
若cale(x,y)>cale(y,z)
1.x[i]>cale(x,y)>cale(y,z)则z更优
2.x[i]<cale(x,y),则x更优
因为x[i]递增,情况1保持不变,情况2可能会变成情况1还是不可能取y
综上当cale(x,y)>cale(y,z)时可以踢掉y,即维护斜率递增
题干:
题目背景 小B的班级数学学到多项式乘法了,于是小B给大家出了个问题:用编程序来解决多项式乘法的问题。
题目描述 L公司有N个工厂,由高到底分布在一座山上。 工厂1在山顶,工厂N在山脚。 由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用。 突然有一天,L公司的总裁L先生接到气象部门的电话,被告知三天之后将有一场暴雨,于是L先生决定紧急在某些工厂建立一些仓库以免产品被淋坏。 由于地形的不同,在不同工厂建立仓库的费用可能是不同的。第i个工厂目前已有成品Pi件,在第i个工厂位置建立仓库的费用是Ci。 对于没有建立仓库的工厂,其产品应被运往其他的仓库进行储藏,而由于L公司产品的对外销售处设置在山脚的工厂N,故产品只能往山下运(即只能运往编号更大的工厂的仓库),当然运送产品也是需要费用的,假设一件产品运送1个单位距离的费用是1。 假设建立的仓库容量都都是足够大的,可以容下所有的产品。你将得到以下数据: 工厂i距离工厂1的距离Xi(其中X1=);
工厂i目前已有成品数量Pi;
在工厂i建立仓库的费用Ci; 请你帮助L公司寻找一个仓库建设的方案,使得总的费用(建造费用+运输费用)最小。
输入输出格式
输入格式: 第一行包含一个整数N,表示工厂的个数。接下来N行每行包含两个整数Xi, Pi, Ci, 意义如题中所述。 输出格式: 仅包含一个整数,为可以找到最优方案的费用。
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(register int i = a;i <= n;i++)
#define lv(i,a,n) for(register int i = a;i >= n;i--)
#define clean(a) memset(a,0,sizeof(a))
const int INF = << ;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
char c;
bool op = ;
while(c = getchar(), c < '' || c > '')
if(c == '-') op = ;
x = c - '';
while(c = getchar(), c >= '' && c <= '')
x = x * + c - '';
if(op) x = -x;
}
template <class T>
void write(T x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar('' + x % );
}
const int N = 1e6 + ;
int n,m,x[N],q[N],c[N];
ll f[N],ss[N],s[N];
db calc(int j,int k)
{
return (f[k] - f[j] + ss[k] - ss[j]) * 1.0 / (s[k] - s[j]);
}
int main()
{
read(n);
duke(i,,n)
{
read(x[i]);read(s[i]);read(c[i]);
ss[i] = ss[i - ] + x[i] * s[i];
s[i] += s[i - ];
}
for(int i = ,l = ,r = ;i <= n;i++)
{
while(l < r && x[i] > calc(q[l],q[l + ])) l++;
f[i] = f[q[l]] + c[i] - ss[i] + ss[q[l]] + x[i] * (s[i] - s[q[l]]);
while(l < r && calc(q[r - ],q[r]) > calc(q[r],i)) r--;
q[++r] = i;
}
printf("%lld\n",f[n]);
return ;
}
P2120 [ZJOI2007]仓库建设 斜率优化dp的更多相关文章
- 洛谷P2120 [ZJOI2007]仓库建设 斜率优化DP
做的第一道斜率优化\(DP\)QwQ 原题链接1/原题链接2 首先考虑\(O(n^2)\)的做法:设\(f[i]\)表示在\(i\)处建仓库的最小费用,则有转移方程: \(f[i]=min\{f[j] ...
- bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)
题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L ...
- BZOJ 1096: [ZJOI2007]仓库建设 [斜率优化DP]
1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4201 Solved: 1851[Submit][Stat ...
- bzoj1096[ZJOI2007]仓库建设 斜率优化dp
1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5482 Solved: 2448[Submit][Stat ...
- 【bzoj1096】[ZJOI2007]仓库建设 斜率优化dp
题目描述 L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用.突然有一天,L公司的总裁L ...
- [ZJOI2007] 仓库建设 - 斜率优化dp
大脑真是个很优秀的器官,做事情之前总会想着这太难,真的逼着自己做下去,回头看看,其实也不过如此 很朴素的斜率优化dp了 首先要读懂题目(我的理解能力好BUG啊) 然后设\(dp[i]\)表示处理完前\ ...
- 【BZOJ-1096】仓库建设 斜率优化DP
1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3719 Solved: 1633[Submit][Stat ...
- 【BZOJ1096】[ZJOI2007]仓库建设 斜率优化
[BZOJ1096][ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司 ...
- [ZJOI2007]仓库建设(斜率优化)
L公司有N个工厂,由高到底分布在一座山上. 工厂1在山顶,工厂N在山脚. 由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用. 突然有一天,L公司的总裁L先生接到气象部 ...
随机推荐
- 洛谷——P3275 [SCOI2011]糖果
P3275 [SCOI2011]糖果 差分约束模板题,基本思路就是$d[v]+w[v,u]<=d[u]$,$Spfa$更新方法, 有点套路的是要建立原点,即图中不存在的点来向每个点加边,但同样这 ...
- 剑指offer---圆圈中最后剩下的数
题目:圆圈中最后剩下的数 要求:0,1,2...n-1 共n个数排成一个圆圈,从数字0开始,每次删除第m个元素,求这个圆圈里面剩下的最后一个元素 如 n=5, m=3 的情况:0, 1, 2, 3, ...
- Go:字符串操作
Package strings:https://golang.google.cn/pkg/strings/ package main import ( "fmt" "st ...
- Python面向对象类的特殊成员方法
类的特殊成员方法:1.__doc__ : 打印类下面的注释 2.__module__和__class__:from lib.aa import C输出类被导出的模块名lib.aa,输出类的模块名和类名 ...
- 搭建一台功能简单的FTP服务器
#vi /etc/sysconfig/network-scripts/ifcfg-eno33554952 #revice network restart #ping www.baidu.com #ip ...
- (七)python3 切片
切片:取一个 list 或 tuple 的部分元素是非常常见的操作 >>> L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack'] #笨办法 ...
- HDU 4903 (模拟+贪心)
Fighting the Landlords Problem Description Fighting the Landlords is a card game which has been a he ...
- [Usaco2016 Open]Diamond Collector
题目描述 Bessie the cow, always a fan of shiny objects, has taken up a hobby of mining diamonds in her s ...
- wait、notify应用场景(生产者-消费者模式)
Java实现生产者消费者的方式有:wait && notify.BlockingQueue.Lock && Condition等 wait.notify注意事项:(1) ...
- Windows 10+Ubuntu 16.04在MBR分区上安装双系统(转)
以下内容转自这篇博客: http://www.cnblogs.com/Duane/p/5424218.html http://www.cnblogs.com/Duane/p/6776302.html( ...