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(锯木厂选址)相关推荐

  1. cogs 362. [CEOI2004]锯木厂选址

    ★★★   输入文件:two.in   输出文件:two.out   简单对比 时间限制:0.1 s   内存限制:32 MB 从山顶上到山底下沿着一条直线种植了n棵老树.当地的政府决定把他们砍下来. ...

  2. [题解]CEOI 2004 锯木厂选址

    [题目描述] 从山顶上到山底下沿着一条直线种植了n棵老树.当地的政府决定把他们砍下来.为了不浪费任何一棵木材,树被砍倒后要运送到锯木厂.木材只能按照一个方向运输:朝山下运.山脚下有一个锯木厂.另外两个 ...

  3. 【斜率优化】[CEOI2004]锯木厂选址——从这里开始斜率优化的大门

    题目 好久没有碰过斜率优化了,我们从这里来开始复习一下, 先看一下题目: 从山顶上到山底下沿着一条直线种植了n棵老树.当地的政府决定把他们砍下来.为了不浪费任何一棵木材,树被砍倒后要运送到锯木厂.木材 ...

  4. 关于最近打的几题斜率优化的总结。加几AC代码。

    斜率优化错误总结 网上说很多OJ桑的斜率优化大多都是模板题- -,结果每次都跪Orz...在此总结一些常见错误: 1:不得不说斜率优化很多时候计算式很长- -,代码容易错细节- -. 2:其次就是弹队 ...

  5. 提高篇 第五部分 动态规划 第6章 斜率优化动态规划

    例1 任务安排(TYVJ1098) [tyvj1098]任务安排(dp)_薇小薇-CSDN博客 Tyvj1098 任务安排_Monster__Yi的博客-CSDN博客 P2365 任务安排 任务安排 ...

  6. 《信息学奥赛一本通》提高版题单

    第一部分 基础算法 第 1 章 贪心算法 #10000 「一本通 1.1 例 1」活动安排 #10001 「一本通 1.1 例 2」种树 #10002 「一本通 1.1 例 3」喷水装置 #10003 ...

  7. 斜率优化dp 的简单入门

    不想写什么详细的讲解了...而且也觉得自己很难写过某大佬(大米饼),于是建议把他的 blog 先看一遍,然后自己加了几道题目以及解析...顺便建议看看算法竞赛(蓝皮书)的 0x5A 斜率优化(P294 ...

  8. 一本通提高篇在线提交地址

    一本通提高篇 1 基础算法 1.1 贪心算法 1.1.1 P2018  [第一章例题1.1]活动安排正确: 9 提交: 17 比率: 52.94 % 1.1.2 P2021 [第一章例题1.2]种树正 ...

  9. DP总结 ——QPH

    常见优化 单调队列 形式 dp[i]=min{f(k)} dp[i]=max{f(k)} 要求 f(k)是关于k的函数 k的范围和i有关 转移方法 维护一个单调递增(减)的队列,可以在两头弹出元素,一 ...

最新文章

  1. 美国运通使用AI技术检测欺诈行为 增强安全性
  2. 用jdk在cmd下运行编译java程序
  3. python中的rstrip函数_Python strip() lstrip() rstrip() 函数 去除空格
  4. jmeter控制器--if控制器
  5. Redis系列教程(七):Redis并发竞争key的解决方案详解
  6. SQL优化一例:GROUP BY的语句
  7. 80C51汇编语言有哪几条常用伪指令,单片微机原理与接口技术答案(宋跃版)
  8. 在Android系统中添加宏控制代码【原创】
  9. Markdown表格——复杂表格
  10. python zemax_python的用途和优点
  11. 1秒究竟等于多少毫秒?
  12. 数据库相关基础知识总结
  13. 努比亚android最高版本,努比亚Z11安卓7.1固件开发版下载地址:新增压力按键等功能...
  14. 单双节锂电池6-8.4V升压9V ,12V,24V快充PD升压系统解决方案
  15. day19 part1:网络安全态势感知
  16. 微谈网页设计颜色搭配原则与方法
  17. Rufus 格式化和创建可引导U盘的工具
  18. 收藏!Latex简明速查手册
  19. 最全阿里技术P系列解读:P5-P8的技能要求和薪资结构
  20. 社保卡当银行卡用如何随时知道钱的多少?

热门文章

  1. 战五渣系列之六(5分钟还搞不懂多线程?)
  2. 对新入职员工五个问题的简答
  3. 如何修改集群的公网信息(包括 VIP) (文档 ID 1674442.1)
  4. 渤海银行与金融壹账通战略签约 打通数字转型技术壁垒
  5. 人工智能和智能城市两者之间,有什么关系?
  6. 解决Mac网易云音乐下载管理识别不到mp3歌曲(修改Comment)
  7. Dual Processor vs Dual Core
  8. 【C语言基础07】while语句的定义、使用、功能、例子、注意事项
  9. 数据分析初学者必备!5分钟搭建波士顿矩阵模型,一学就会
  10. 利用Windows Media Player实现倍速播放本地视频