斜率在转移顺序下不满足单调性的斜率优化\(DP\),用动态凸包来维护。送命题。

简化版题意:每次在凸包上插入一个点,以及求一条斜率为\(K\)的直线与当前凸包的交点。思路简单实现困难。

\(P.s\),不是特别建议用\(Set\)来维护动态凸包,万一中间哪一点功能实现\(STL\)没有提供就\(GG\)了。(比如要有两种比较运算符。)本人因此重构了三次\(:)\)

代码来源:黄学长的代码的魔改版。

#include <bits/stdc++.h>
using namespace std; const double eps = 1e-8;
const int N = 100000 + 5; int n, top, sta[N]; double f[N]; struct point {
double x, y, a, b, k, rate; int w, id;
}p[N], t[N]; double getk (int a, int b) {
if (b == 0) return -1e20;
if (fabs (p[a].x - p[b].x) < eps) {
return 1e20;
} else {
return (p[b].y - p[a].y) / (p[b].x - p[a].x);
}
} bool operator < (point a, point b) {
return a.k > b.k;
} void solve (int l, int r) {
if (l == r) {
f[l] = max (f[l], f[l - 1]);
p[l].y = f[l] / (p[l].a * p[l].rate + p[l].b);
p[l].x = p[l].rate * p[l].y;
return;
}//分治到底了显然我们可以直接计算出结果
int l1, l2, mid = (l + r) >> 1, j = 1;
//============================================================================
l1 = l; l2 = mid + 1;
for (int i = l; i <= r; i++) {
if (p[i].id <= mid) {
t[l1++] = p[i];
} else {
t[l2++] = p[i];
}
}
for (int i = l; i <= r; i++) {
p[i] = t[i];
}
solve (l, mid);//递归左边
top = 0;
for (int i = l; i <= mid; i++) {
while (top > 1 && getk (sta[top - 1], sta[top]) < getk (sta[top - 1], i) + eps) {
top--;
}
sta[++top] = i;
}//左边维护一个凸包
sta[++top] = 0;
for (int i = mid + 1; i <= r; i++) {
while (j < top && getk (sta[j], sta[j + 1]) + eps > p[i].k) {
j++;
}//用左边的点作为决策更新右边
f[p[i].id] = max (f[p[i].id], p[sta[j]].x * p[i].a + p[sta[j]].y * p[i].b);
}
solve (mid + 1, r);//递归右边
l1 = l; l2 = mid + 1;
for (int i = l; i <= r; i++) {
if (((p[l1].x < p[l2].x || (fabs(p[l1].x - p[l2].x) < eps && p[l1].y < p[l2].y)) || l2 > r) && l1 <= mid) {
t[i] = p[l1++];
} else {
t[i] = p[l2++];
}
}
for (int i = l; i <= r; i++) p[i] = t[i];
} int main () {
// freopen ("data.in", "r", stdin);
cin >> n >> f[0];
for (int i = 1; i <= n; i++) {
cin >> p[i].a >> p[i].b >> p[i].rate;
p[i].k = -p[i].a / p[i].b; p[i].id = i;
}
sort (p + 1, p + n + 1);//这里按照斜率进行排序,保证分治的每一块斜率是有序的
solve (1, n);
cout << fixed << setprecision (10) << f[n] << endl;
}

【BZOJ1492】【Luogu P4027】 [NOI2007]货币兑换 CDQ分治,平衡树,动态凸包的更多相关文章

  1. LUOGU P4027 [NOI2007]货币兑换 (斜率优化+CDQ分治)

    传送门 解题思路 题目里有两句提示一定要看清楚,要不全买要不全卖,所以dp方程就比较好列,f[i]=max(f[j]*rate[j]*a[i])/(rate[j]*a[j]+b[j])+(f[j]*b ...

  2. [NOI2007]货币兑换 cdq分治,斜率优化

    [NOI2007]货币兑换 LG传送门 妥妥的\(n \log n\)cdq做法. 这题用cdq分治也可以\(n \log n\)但是在洛谷上竟然比一些优秀的splay跑得慢真是见了鬼了看来还是人丑常 ...

  3. [NOI2007]货币兑换Cash(DP+动态凸包)

    第一次打动态凸包维护dp,感觉学到了超级多的东西. 首先,set是如此的好用!!!可以通过控制一个flag来实现两种查询,维护凸包和查找斜率k 不过就是重载运算符和一些细节方面有些恶心,90行解决 后 ...

  4. P4027 [NOI2007]货币兑换(斜率优化dp+cdq分治)

    P4027 [NOI2007]货币兑换 显然,如果某一天要买券,一定是把钱全部花掉.否则不是最优(攒着干啥) 我们设$f[j]$为第$j$天时用户手上最多有多少钱 设$w$为花完钱买到的$B$券数 $ ...

  5. 洛谷 P4027 [NOI2007]货币兑换 解题报告

    P4027 [NOI2007]货币兑换 题目描述 小 \(Y\) 最近在一家金券交易所工作.该金券交易所只发行交易两种金券:\(A\) 纪念券(以下简称 \(A\) 券)和 \(B\) 纪念券(以下简 ...

  6. 洛谷P4027 [NOI2007]货币兑换

    P4027 [NOI2007]货币兑换 算法:dp+斜率优化 题面十分冗长,题意大概是有一种金券每天价值会有变化,你可以在某些时间点买入或卖出所有的金券,问最大收益 根据题意,很容易列出朴素的状态转移 ...

  7. BZOJ_1492_[NOI2007]货币兑换Cash_CDQ分治+斜率优化

    BZOJ_1492_[NOI2007]货币兑换Cash_CDQ分治+斜率优化 Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券 ...

  8. LOJ 2353 & 洛谷 P4027 [NOI2007]货币兑换(CDQ 分治维护斜率优化)

    题目传送门 纪念一下第一道(?)自己 yy 出来的 NOI 题. 考虑 dp,\(dp[i]\) 表示到第 \(i\) 天最多有多少钱. 那么有 \(dp[i]=\max\{\max\limits_{ ...

  9. BZOJ1492 货币兑换 CDQ分治优化DP

    1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec  Memory Limit: 64 MB Description 小Y最近在一家金券交易所工作.该金券交易所只发行交 ...

随机推荐

  1. Linux 查找当前目录下 包含特定字符串 的所有文件

    使用 Linux 经常会遇到这种情况:只知道文件中包含某些特定的字符串,但是不知道具体的文件名.需要根据“特定的字符串”反向查找文件. 示例(路径文件如下): ./miracle/luna/a.txt ...

  2. 网易云课堂_C++程序设计入门(下)_第9单元:白公曾咏牡丹芳,一种鲜妍独“异常”_第9单元 - 作业5:OJ编程 - 使用异常进行图形类的错误处理

    第9单元 - 作业5:OJ编程 - 使用异常进行图形类的错误处理 查看帮助 返回   温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截止时间之前 ...

  3. caffe-----silence layer 作用

    最近看到prototxt里面有silence这个层,好奇是干什么用的,而且看源码也出奇的简单: #include <vector> #include "caffe/layers/ ...

  4. 【SVN】更新提交失败---- Previous operation has not finished; run 'cleanup' if it was interrupted解决方法

     Previous operation has not finished; run 'cleanup' if it was interrupted 问题出处 解决方法 2017-11-01   08: ...

  5. 如何解决idea本身的乱码以及解决代码中出现的乱码?

    1:解决idea中控制台的乱码现象(3中方法): 第一种: 如图需要找到idea的安装路径: idea\IntelliJ IDEA 2018.3.2\bin 在这个路径下面有一个文件叫:idea64. ...

  6. Hand on Machine Learning 第三章:分类器

    1. 获取数据 使用MNIST数据集练习分类任务 from sklearn.datasets import fetch_mldata from scipy.io import loadmat mnis ...

  7. 【VS开发】【智能语音处理】语音信号处理之(一)动态时间规整(DTW)

    语音信号处理之(一)动态时间规整(DTW) zouxy09@qq.com http://blog.csdn.net/zouxy09 这学期有<语音信号处理>这门课,快考试了,所以也要了解了 ...

  8. HDU 1029 Ignatius and the Princess IV (动态规划、思维)

    Ignatius and the Princess IV Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32767 K ( ...

  9. HDU 1250 Hat's Fibonacci (递推、大数加法、string)

    Hat's Fibonacci Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  10. [转帖]影驰首发PCIe 4.0 SSD:群联AMD合作主控飚出5GB/s

    影驰首发PCIe 4.0 SSD:群联AMD合作主控飚出5GB/s https://www.cnbeta.com/articles/tech/851275.htm 硬件发展的真快.. AMD刚刚发布的 ...