Two Sawmills(锯木厂选址)
http://main.edu.pl/en/archive/ceoi/2004/two
斜率优化DP,应该说是第一道斜率优化DP了,推公式的时候各种坑,还是参照了hzq神牛的思路,细节方面稍有不同,
为了思维方便,我先将给出的序列翻转了,也就是把从山顶到山下的点顺序边成了从山下到山顶,编号从1开始,第一个点即为海拔最低的伐木场,所以共有n+1个点,w[i]表示第i个点的重量,dist[i]表示第i个点到第一个点的距离,dp[i]表示把第二个伐木场建到第i个点的最优解
则有
dp[i] = min(S[1, j-1]+S[j, i-1]+S[i, n+1]) 1
其中 S[l, r] = ∑w[i]*(dist[i]-dist[i]) (l <= i <= r) 2
再设sw[i] = ∑ w[j] (1 <= j <= i), 3
swd[i] = ∑ w[j]*dist[j] (1 <= j <= i) 4
则有 S[l, r] = swd[r]-swd[l-1]-(sw[r]-sw[l-1])*dist[l];
带入1式后化简可得
dp[i] = min(swd[n+1]-swd[0]-(sw[n+1]-sw[i-1])*dist[i]-(sw[i-1]-sw[j-1])*dist[j]-(sw[j-1]-sw[0])*dist[1])
由于dist[1]等于0,所以
dp[i] = min(-(sw[i-1]-sw[j-1])*dist[j])+swd[n+1]-swd[0]-(sw[n+1]-sw[i-1])*dist[i]
以为后面的部分是与j无关的常量,所以不会影响决策,可以忽略掉
所以要求解只剩min((-sw[i-1])*dist[j]+sw[j-1]*dist[j])了
由于-sw[i-1]在第i轮决策中可以看成常数记为a,用x表示dist[j],y表示sw[j-1]*dist[j],
则优化目标G = min(-ax+y),设x*,y*为最优解(注意最优解实际上只有j决定)
则有G = -ax*+y*,移项后可得y* = ax*+G,由于a > 0所以,这相当于一条斜率已知的直线向上移动直到与之前任意一个点(x, y) 想切,此时的到的G是最优解,不难发现最优决策点构成一条下凸线,而且由于a单调递增,而下凸线的斜率也是单调递增的,所以可以舍弃当前最优决策之前的所有点,因为这些点都不可能成为之后决策的最优点了。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cctype>
#include <utility>
#include <map>
#include <string>
#include <climits>
#include <set>
#include <string>
#include <sstream>
#include <utility>
#include <ctime>
#include <bitset>using std::priority_queue;
using std::vector;
using std::swap;
using std::stack;
using std::sort;
using std::max;
using std::min;
using std::pair;
using std::map;
using std::string;
using std::cin;
using std::cout;
using std::set;
using std::queue;
using std::string;
using std::stringstream;
using std::make_pair;
using std::getline;
using std::greater;
using std::endl;
using std::multimap;
using std::deque;
using std::unique;
using std::lower_bound;
using std::random_shuffle;
using std::bitset;
using std::upper_bound;
using std::multiset;typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PAIR;
typedef multimap<int, int> MMAP;
typedef LL TY;
typedef long double LF;const int MAXN(20010);
const int MAXM(100010);
const int MAXE(100010);
const int MAXK(6);
const int HSIZE(31313);
const int SIGMA_SIZE(26);
const int MAXH(19);
const int INFI((INT_MAX-1) >> 1);
const ULL BASE(31);
const LL LIM(10000000);
const int INV(-10000);
const int MOD(20100403);
const double EPS(1e-7);
const LF PI(acos(-1.0));template<typename T> void checkmax(T &a, T b){if(b > a) a = b;}
template<typename T> void checkmin(T &a, T b){if(b < a) a = b;}
template<typename T> T ABS(const T &a){return a < 0? -a: a;}LL X[MAXN], Y[MAXN];
int que[MAXN];
int front, back;
LL dist[MAXN], sw[MAXN];int main()
{int n;while(~scanf("%d", &n)){++n; //一共n+1个点,下标1从开始LL swd = 0;for(int i = n; i >= 2; --i)scanf("%I64d%I64d", sw+i, dist+i);for(int i = 1; i <= n; ++i){dist[i] += dist[i-1];swd += dist[i]*sw[i];sw[i] += sw[i-1];}for(int i = 1; i <= n; ++i){X[i] = dist[i];Y[i] = sw[i-1]*dist[i];}LL ans = 1e11;front = 0;back = -1;que[++back] = 1;que[++back] = 2; for(int i = 3; i <= n; ++i){while(back-front > 0 && (-sw[i-1])*X[que[front+1]]+Y[que[front+1]] <= (-sw[i-1])*(X[que[front]])+Y[que[front]]) ++front;checkmin(ans, swd-(sw[n]-sw[i-1])*dist[i]+((-sw[i-1])*(X[que[front]])+Y[que[front]]));while(back-front > 0 && (Y[i]-Y[que[back-1]])*(X[i]-X[que[back]]) >= (Y[i]-Y[que[back]])*(X[i]-X[que[back-1]])) --back;que[++back] = i;}printf("%I64d\n", ans);}return 0;
}
Two Sawmills(锯木厂选址)相关推荐
- cogs 362. [CEOI2004]锯木厂选址
★★★ 输入文件:two.in 输出文件:two.out 简单对比 时间限制:0.1 s 内存限制:32 MB 从山顶上到山底下沿着一条直线种植了n棵老树.当地的政府决定把他们砍下来. ...
- [题解]CEOI 2004 锯木厂选址
[题目描述] 从山顶上到山底下沿着一条直线种植了n棵老树.当地的政府决定把他们砍下来.为了不浪费任何一棵木材,树被砍倒后要运送到锯木厂.木材只能按照一个方向运输:朝山下运.山脚下有一个锯木厂.另外两个 ...
- 【斜率优化】[CEOI2004]锯木厂选址——从这里开始斜率优化的大门
题目 好久没有碰过斜率优化了,我们从这里来开始复习一下, 先看一下题目: 从山顶上到山底下沿着一条直线种植了n棵老树.当地的政府决定把他们砍下来.为了不浪费任何一棵木材,树被砍倒后要运送到锯木厂.木材 ...
- 关于最近打的几题斜率优化的总结。加几AC代码。
斜率优化错误总结 网上说很多OJ桑的斜率优化大多都是模板题- -,结果每次都跪Orz...在此总结一些常见错误: 1:不得不说斜率优化很多时候计算式很长- -,代码容易错细节- -. 2:其次就是弹队 ...
- 提高篇 第五部分 动态规划 第6章 斜率优化动态规划
例1 任务安排(TYVJ1098) [tyvj1098]任务安排(dp)_薇小薇-CSDN博客 Tyvj1098 任务安排_Monster__Yi的博客-CSDN博客 P2365 任务安排 任务安排 ...
- 《信息学奥赛一本通》提高版题单
第一部分 基础算法 第 1 章 贪心算法 #10000 「一本通 1.1 例 1」活动安排 #10001 「一本通 1.1 例 2」种树 #10002 「一本通 1.1 例 3」喷水装置 #10003 ...
- 斜率优化dp 的简单入门
不想写什么详细的讲解了...而且也觉得自己很难写过某大佬(大米饼),于是建议把他的 blog 先看一遍,然后自己加了几道题目以及解析...顺便建议看看算法竞赛(蓝皮书)的 0x5A 斜率优化(P294 ...
- 一本通提高篇在线提交地址
一本通提高篇 1 基础算法 1.1 贪心算法 1.1.1 P2018 [第一章例题1.1]活动安排正确: 9 提交: 17 比率: 52.94 % 1.1.2 P2021 [第一章例题1.2]种树正 ...
- DP总结 ——QPH
常见优化 单调队列 形式 dp[i]=min{f(k)} dp[i]=max{f(k)} 要求 f(k)是关于k的函数 k的范围和i有关 转移方法 维护一个单调递增(减)的队列,可以在两头弹出元素,一 ...
最新文章
- 美国运通使用AI技术检测欺诈行为 增强安全性
- 用jdk在cmd下运行编译java程序
- python中的rstrip函数_Python strip() lstrip() rstrip() 函数 去除空格
- jmeter控制器--if控制器
- Redis系列教程(七):Redis并发竞争key的解决方案详解
- SQL优化一例:GROUP BY的语句
- 80C51汇编语言有哪几条常用伪指令,单片微机原理与接口技术答案(宋跃版)
- 在Android系统中添加宏控制代码【原创】
- Markdown表格——复杂表格
- python zemax_python的用途和优点
- 1秒究竟等于多少毫秒?
- 数据库相关基础知识总结
- 努比亚android最高版本,努比亚Z11安卓7.1固件开发版下载地址:新增压力按键等功能...
- 单双节锂电池6-8.4V升压9V ,12V,24V快充PD升压系统解决方案
- day19 part1:网络安全态势感知
- 微谈网页设计颜色搭配原则与方法
- Rufus 格式化和创建可引导U盘的工具
- 收藏!Latex简明速查手册
- 最全阿里技术P系列解读:P5-P8的技能要求和薪资结构
- 社保卡当银行卡用如何随时知道钱的多少?
热门文章
- 战五渣系列之六(5分钟还搞不懂多线程?)
- 对新入职员工五个问题的简答
- 如何修改集群的公网信息(包括 VIP) (文档 ID 1674442.1)
- 渤海银行与金融壹账通战略签约 打通数字转型技术壁垒
- 人工智能和智能城市两者之间,有什么关系?
- 解决Mac网易云音乐下载管理识别不到mp3歌曲(修改Comment)
- Dual Processor vs Dual Core
- 【C语言基础07】while语句的定义、使用、功能、例子、注意事项
- 数据分析初学者必备!5分钟搭建波士顿矩阵模型,一学就会
- 利用Windows Media Player实现倍速播放本地视频