[BSOJ2684]锯木厂选址(斜率优化)
Description
从山顶上到山底下沿着一条直线种植了n棵老树。当地的政府决定把他们砍下来。为了不浪费任何一棵木材,树被砍倒后要运送到锯木厂。木材只能按照一个方向运输:朝山下运。山脚下有一个锯木厂。另外两个锯木厂将新修建在山路上。你必须决定在哪里修建两个锯木厂,使得传输的费用总和最小。假定运输每公斤木材每米需要一分钱。任务你的任务是写一个程序:从标准输入读入树的个数和他们的重量与位置计算最小运输费用将计算结果输出到标准输出(2≤n≤20 000)
Solution
设\(S[i]\)为重量前缀和,\(Sd[i]\)为距离前缀和,\(d[i]\)为第\(i\)棵树到第\(i+1\)棵树的距离
那么第一个锯木厂费用:\(Cost[i]=Cost[i-1]+S[i-1]*d[i-1]\)
而到第二个锯木厂费用:\(W(i,j)=Cost[j]-Cost[i-1]-S[i-1]*(Sd[j]-Sd[i-1])\)
那么\(Ans=min\{Cost[j]+W(j+1,i)+W(i+1,n+1)\}\)
乱搞一下发现斜率式,此时\(i>k>j\),且\(k\)比\(j\) 优
\(\frac{S[j]*Sd[j]-S[k]*Sd[k]}{S[j]-S[k]}<Sd[i]\)
然后就完了
Tips:
由于\(S[k]>S[j]\)所以\(S[j]-S[k]<0\) 把斜率式变形的时候记得变符号
因为不知道在哪设锯木厂最优,用一个\(Ans\)变量随时更新,否则WA
虽然答案在int范围,但是如果化除为乘的话中间结果要long long
Code
#include <cstdio>
#include <algorithm>
#define N 20010
using namespace std;
int n,d[N],s[N],sd[N],cost[N],Ans;
int l,r,q[N];
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline void Init(){
n=read();
for(int i=1;i<=n;++i){
s[i]=s[i-1]+read(),d[i]=read();
sd[i]=sd[i-1]+d[i-1];
cost[i]=cost[i-1]+d[i-1]*s[i-1];
}
s[n+1]=s[n];
sd[n+1]=sd[n]+d[n];
cost[n+1]=cost[n]+d[n]*s[n];
}
inline int f(int j,int k){return s[j]*sd[j]-s[k]*sd[k];}
inline int g(int j,int k){return s[j]-s[k];}
int h(int i,int j){return cost[n+1]-s[j]*(sd[i]-sd[j])-s[i]*(sd[n+1]-sd[i]);}
inline void DP(){
l=r=1;Ans=1e9;
for(int i=1;i<=n;++i){
while(l<r&&f(q[l],q[l+1])>sd[i]*1ll*g(q[l],q[l+1])) l++;
int j=q[l];
Ans=min(Ans,h(i,j));
while(l<r&&f(q[r],i)*1ll*g(q[r-1],q[r])<g(q[r],i)*1ll*f(q[r-1],q[r])) r--;
q[++r]=i;
}
}
int main(){
Init();
DP();
printf("%d\n",Ans);
return 0;
}
[BSOJ2684]锯木厂选址(斜率优化)的更多相关文章
- [CEOI2004]锯木厂选址 斜率优化DP
斜率优化DP 先考虑朴素DP方程, f[i][k]代表第k个厂建在i棵树那里的最小代价,最后答案为f[n+1][3]; f[i][k]=min(f[j][k-1] + 把j+1~i的树都运到i的代价) ...
- 【BZOJ2684】【CEOI2004】锯木厂选址(斜率优化,动态规划)
[BZOJ2684][CEOI2004]锯木厂选址(斜率优化,动态规划) 题面 万恶的BZOJ因为权限题的原因而做不了... 我要良心的提供题面 Description 从山顶上到山底下沿着一条直线种 ...
- luoguP4360 [CEOI2004]锯木厂选址
题目链接 luoguP4360 [CEOI2004]锯木厂选址 题解 dis:后缀和 sum:前缀和 补集转化,减去少走的,得到转移方程 dp[i] = min(tot - sumj * disj - ...
- P4360 [CEOI2004]锯木厂选址
P4360 [CEOI2004]锯木厂选址 这™连dp都不是 \(f_i\)表示第二个锯木厂设在\(i\)的最小代价 枚举1号锯木厂 \(f_i=min_{0<=j<i}(\sum_{i= ...
- luogu4360 锯木厂选址 (斜率优化dp)
设: sw[i]为1..i的w之和 sd[i]为1到i的距离 cost[i]为把第一个锯木厂建在i带来的花费 all[i,j]为把i..j所有木头运到j所需要的花费 所以$all[i,j]=cost[ ...
- 2018.08.28 洛谷P4360 [CEOI2004]锯木厂选址(斜率优化dp)
传送门 一道斜率优化dp入门题. 是这样的没错... 我们用dis[i]表示i到第三个锯木厂的距离,sum[i]表示前i棵树的总重量,w[i]为第i棵树的重量,于是发现如果令第一个锯木厂地址为i,第二 ...
- 洛谷P4360 [CEOI2004]锯木厂选址(斜率优化)
传送门 我可能根本就没有学过斜率优化…… 我们设$dis[i]$表示第$i$棵树到山脚的距离,$sum[i]$表示$w$的前缀和,$tot$表示所有树运到山脚所需要的花费,$dp[i]$表示将第二个锯 ...
- 动态规划(斜率优化):[CEOI2004]锯木厂选址
锯木场选址(CEOI2004) 从山顶上到山底下沿着一条直线种植了n棵老树.当地的政府决定把他们砍下来.为了不浪费任何一棵木材,树被砍倒后要运送到锯木厂. 木材只能按照一个方向运输:朝山下运.山脚下有 ...
- 【CEOI2004】锯木厂选址
[题目描述] 从山顶上到山底下沿着一条直线种植了n棵老树.当地的政府决定把他们砍下来.为了不浪费任何一棵木材,树被砍倒后要运送到锯木厂.木材只能按照一个方向运输:朝山下运.山脚下有一个锯木厂.另外两个 ...
随机推荐
- JS展示预览PDF。
刚好遇到需求,需要在手机端--展示一个电子收据,电子收据返回是PDF格式的,所以需要在前端上面去做PDF预览. 在学习过程中,了解到一种很简单,不需要任何插件的方法做PDF预览,但是这方法有局限性. ...
- C#在VS2005开发环境中利用异步模式来对一个方法的执行时间进行超时控制
using System.Threading; using System; namespace ConsoleApplication4 { public class Program { static ...
- (转载)ASP.NET Quiz Answers: Does Page.Cache leak memory?
原文地址:http://blogs.msdn.com/b/tess/archive/2006/08/11/695268.aspx "We use Page.Cache to store te ...
- 北航oo作业第二单元小结
类的设计: 首先,我对我的思路进行整体的说明,由于我的三次作业,思路是继承的,所以做总体的说明 第一, Main类,Main类自身并没有功能,他的功能只是构造需要的电梯线程和输入线程. 其中,第三 ...
- 数据库(DBUtils)
DBUtils和连接池 今日内容介绍 u DBUtils u 连接池 第1章 DBUtils 如果只使用JDBC进行开发,我们会发现冗余代码过多,为了简化JDBC开发,本案例我们讲采用apache c ...
- 零基础逆向工程26_C++_03_Vector
1 Vector 核心代码 #define SUCCESS 1 // 成功 #define ERROR -1 // 失败 #define MALLOC_ERROR -2 // 申请内存失败 #defi ...
- Mybatis介绍(一)
这里介绍的mybatis比较简单, 我做为一个初学者, 记录下个人在学习中方法, 如果那里出错, 希望读者朋友们见谅. 首先这里介绍一下我们下面用的表结构: author表是保存了作者的个人信息, 因 ...
- JFinal常量配置学习笔记
在继承 JFinalConfig 类时,需要 实现 /** * Config constant */ public abstract void configConstant(Constants me) ...
- mongodb 入坑
一.安装mongodb https://www.mongodb.com/ 官网下载合适的版本,安装在C或者D盘,我选择的是默认路径C:\Program Files\MongoDB\Server\3.4 ...
- gearmand 编译 could not find gperf
安装步骤: #wget https://launchpad.net/gearmand/1.2/1.1.8/+download/gearmand-1.1.8.tar.gz #tar zxvf gearm ...