[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棵老树.当地的政府决定把他们砍下来.为了不浪费任何一棵木材,树被砍倒后要运送到锯木厂.木材只能按照一个方向运输:朝山下运.山脚下有一个锯木厂.另外两个 ...
随机推荐
- MySQL JOIN | 联结
联结是利用SQL的SELECT能执行的最重要的操作.为了提高存储的有效性和避免数据冗余,往往会将有关联的数据存储在好几张表中,那么怎样用一条SELECT语句就能检索出这些数据呢? 答案是JOIN(联结 ...
- AngularJS(九):路由
本文也同步发表在我的公众号“我的天空” AngularJS路由 AngularJS路由可以让我们通过不同的URL访问不同页面(似乎是废话),其价值主要体现在单页面的web应用中(single page ...
- 学习笔记:MDN的服务器端网站编程
互联网是如何工作的 互联网(Internet)和网络(web) 互联网是基础设施,网络是建立在这种基础设施之上的服务. 网页,网站,网络服务器和搜索引擎的区别是什么? 网页(webpage) 一份能够 ...
- Android 关于Acitivity 的setFlag以及launchmode的总结
Intent几种常见的flags: .FLAG_ACTIVITY_NEW_TASK:当Intent对象包含这个标记时,系统会寻找或创建一个新的task来放置目标Activity,寻找时依据目标Acti ...
- python decorator 用法
https://www.zhihu.com/question/31265857 http://www.cnblogs.com/huxi/archive/2011/03/01/1967600.html ...
- C#使用Aspose.Words操作word文档
最近接到个需求,由于客服这边要导出大量有一定规则的word文件,里面的内容希望系统自动填充,例如 这里我使用Aspose.Words.dll这个类库, 1.首先,我们需要创建模板文件,毕竟有规则的东西 ...
- World Wind Java开发之十四——添加WMS地图服务资源(转)
数据是GIS的核心,没有数据一切无从谈起,Internet上有很多在线WMS地图服务资源,我们可以好好利用这些数据资源,比如天地图.必应地图.NASA.OGC数据服务等等. 在我们国家常用的还是天地图 ...
- Android(java)学习笔记84:SQLiteDatabase的query方法参数
1. SQLiteDatabase的query方法: public Cursor query (boolean distinct, String table, String[] columns, St ...
- 2017.12.9 Java中的排序---冒泡排序、快速排序、选择排序
//冒泡排序 public class demo{ public static void main(String[] args) { int[] sum={2,9,10,1,5,88}; System ...
- jquery iCheck 插件
1 官网:http://www.bootcss.com/p/icheck/#download 2 博客:https://www.cnblogs.com/xcsn/p/6307610.html http ...