【做题】arc072_f-Dam——维护下凸包
题意:有一个容量为\(L\)的水库,每天晚上可以放任意体积的水。每天早上会有一定温度和体积的水流入水库,且要保证流入水之后水的总体积不能超过\(L\)。令体积分别为\(V_1,V_2\),温度分别为\(t_1,t_2\)的水混合后的温度为\(\frac {V_1 * t_1 + V_2 * t_2} {V_1 + V_2}\)。初始水库为空。现给出\(n\)天流入水的体积和温度,分别最大化每一天中午水库满容量时的水温。
\(n <= 500000, \space L,t <= 10^9,\space V <= L\)
显然记录水温时直接记录温度和体积的乘积,这样混合时直接相加就可以了。这个混合满足结合律。
那么,我们可以把水表示为二维平面上的向量,\(x\)坐标为体积,\(y\)坐标为温度和体积的乘积。那么,温度就等于它的斜率。我们贪心一下,如果新加入的水导致水温下降,那么一定会在新加入水后再排水。否则,便可以在新加入水之前排水。这启发我们维护一个下凸包。如果某一天晚上是可以排水的,那么就不先与后面的水混合。否则便把两个向量相加。具体排水时放出斜率较小的水,流入水时不断与现有的水合并直到斜率大于之前的水为止。最大化第\(i+1\)天水的温度,就是最大化第\(i\)天放水后的水温,故我们直接从第\(i\)天的决策更新到第\(i+1\)天的决策,还可以保证新的决策时刻满足水的体积不超过\(L\)。
时间复杂度\(O(n)\)。
#include <bits/stdc++.h>
using namespace std;
const int N = 500010;
typedef double db;
const db eps = 1e-8;
inline int judge(db x) {
return x > -eps ? x > eps ? 1 : 0 : -1;
}
struct point {
db x,y;
point(db x_=0,db y_=0): x(x_), y(y_) {}
db operator * (const point& a) const {
return x * a.y - y * a.x;
}
point operator + (const point& a) const {
return point(x + a.x, y + a.y);
}
point operator - (const point& a) const {
return point(x - a.x, y - a.y);
}
void operator += (const point& a) {
*this = *this + a;
}
void operator -= (const point& a) {
*this = *this - a;
}
} q[N];
int n,cap,t,v,l=1,r;
point cur,tmp;
int main() {
scanf("%d%d",&n,&cap);
scanf("%d%d",&t,&v);
printf("%d.00000000\n",t);
q[++r] = point(v,1.0 * t * v);
cur += point(v,1.0 * t * v);
for (int i = 2 ; i <= n ; ++ i) {
scanf("%d%d",&t,&v);
db a = v;
while (judge(a - q[l].x) >= 0)
a -= q[l].x, cur -= q[l++];
cur -= q[l];
q[l].y *= (q[l].x - a) / q[l].x;
q[l].x -= a;
cur += q[l];
tmp = point(v,1.0 * t * v);
while (l <= r && judge(q[r] * tmp) <= 0)
tmp += q[r], cur -= q[r--];
if (judge(tmp.x - cap) > 0) {
tmp.y *= cap / tmp.x;
tmp.x = cap;
}
q[++r] = tmp;
cur += tmp;
printf("%.8lf\n",cur.y / cur.x);
}
return 0;
}
小结:在贪心的基础上维护下凸包(或单调队列),从而容易转移。感觉自己做起来还有难度。
【做题】arc072_f-Dam——维护下凸包的更多相关文章
- C语言程序设计做题笔记之C语言基础知识(下)
C 语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行 事.并且C是相当灵活的,用于执行计算机程序能完成的 ...
- DP 优化方法大杂烩 & 做题记录 I.
标 * 的是推荐阅读的部分 / 做的题目. 1. 动态 DP(DDP)算法简介 动态动态规划. 以 P4719 为例讲一讲 ddp: 1.1. 树剖解法 如果没有修改操作,那么可以设计出 DP 方案 ...
- SDOI2016 R1做题笔记
SDOI2016 R1做题笔记 经过很久很久的时间,shzr终于做完了SDOI2016一轮的题目. 其实没想到竟然是2016年的题目先做完,因为14年的六个题很早就做了四个了,但是后两个有点开不动.. ...
- AtCoder Grand Contest 11~17 做题小记
原文链接https://www.cnblogs.com/zhouzhendong/p/AtCoder-Grand-Contest-from-11-to-20.html UPD(2018-11-16): ...
- AtCoder Grand Contest 1~10 做题小记
原文链接https://www.cnblogs.com/zhouzhendong/p/AtCoder-Grand-Contest-from-1-to-10.html 考虑到博客内容较多,编辑不方便的情 ...
- HNOI2015做题笔记
HNOI2015 亚瑟王(概率DP) 根据期望的线性性,我们只需要算出每一种卡牌触发的概率就可以算出期望的值 考虑与第\(i\)张卡牌触发概率相关的量,除了\(p_i\)还有前\(i-1\)张卡牌中触 ...
- HNOI2014做题笔记
HNOI2014 世界树(虚树.倍增) \(\sum M \leq 3 \times 10^5\)虚树没得跑 对于所有重要点和它们的\(LCA\)建立虚树,然后计算出每一个虚树上的点被哪个重要点控制. ...
- LIS【p1704】寻找最优美做题曲线
Description 洛谷OJ刷题有个有趣的评测功能,就是系统自动绘制出用户的"做题曲线".所谓做题曲线就是一条曲线,或者说是折线,是这样定义的:假设某用户在第b[i]天AC了c ...
- LIS LCS LCIS (主要过一遍,重在做题)
只详细讲解LCS和LCIS,别的不讲-做题优先. 菜鸟能力有限写不了题解,可以留评论,我给你找博客. 先得理解最长上升子序列吧,那个HDOJ拦截导弹系列可以做一下,然后用o(n)log(n)的在做一遍 ...
随机推荐
- ruby中的alias和alias_method
ruby中的alias和alias_method都可以重命名一个方法,它们的区别如下: 1.alias是ruby的一个关键字,因此使用的时候是alias :newname :oldname alias ...
- html5-浮动
#div1{ background: rgba(255,0,0,0.5); width: 250px; height: 250px; float: right;}#div2{ ...
- 20155228 实验四 Android开发基础
20155228 实验四 Android开发基础 实验内容 1.基于Android Studio开发简单的Android应用并部署测试; 2.了解Android.组件.布局管理器的使用: 3.掌握An ...
- java踩坑
1. java判断两个字符串是否相等用equals 2. java只传递指针遇到的坑: 1 import java.util.*; 2 3 public class mapTest { 4 publi ...
- 主流的Nosql数据库的对比
主流的Nosql数据库的对比 MongoDB,Cassandra,CouchDB,Hypertable, Redis,Riak,Neo4j,Hadoop HBase, Couchbase,Mem ...
- CodeReview实践与总结
CodeReview 是大型软件工程中公认的必不可少的保证工程质量的重要手段之一.但凡正规软件作战军团都是非常重视 CodeReview 的作用和意义的.那么,如何做好 CodeReview 呢?这里 ...
- android TextView Unicde编码转换 android中一些特殊字符Unicode码值
android TextView Unicde编码转换 android中一些特殊字符Unicode码值 android中一些特殊字符(如:←↑→↓等箭头符号,约等于号≍)的Unicode码值 Text ...
- vue 父子组件
组件 什么是组件? 组件 (Component) 是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊 ...
- 什么是 shell
shell 在计算机科学中,Shell俗称壳(用来区别于核),是指“为使用者提供操作界面”的软件(命令解析器).它类似于DOS下的command.com和后来的cmd.exe.它接收用户命令,然后调 ...
- 案例:通过shell脚本实现mysql数据备份与清理
Shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口.它接收用户输入的命令并把它送入内核去执行,实际上Shell是一个命令解释器,它解释由用户输入的命令并且把它们送到内核,不仅如此,Sh ...