[NOI2007]货币兑换

LG传送门

妥妥的\(n \log n\)cdq做法。

这题用cdq分治也可以\(n \log n\)但是在洛谷上竟然比一些优秀的splay跑得慢真是见了鬼了看来还是人丑常数大的问题

先推式子

(这一段与其他题解不会有太多不同,已经了解了的同学可以略过,注意一下转移中\(x\)和\(k\)表示什么就行了。)

设\(f[i]\)表示到第\(i\)天最多有多少钱,\(g[i]\)表示用第\(i\)天时的钱最多能买多少B券,易知\(g[i] = \frac {f[i]} {r[i] * a[i] + b[i]}\)。

得到转移:\(f[i] = \max \{ \max \limits _{j = 1} ^{i - 1} \{g[j] * \frac{b[i]} {a[i]} + r[j] * g[j]\} * a[i], f[i - 1] \}\),外面的\(\max\)可以单独判,里面的\(\max\)可以看出是一个斜率优化的式子(把\(\frac {b[i]} {a[i]}\)视作\(x\),把\(g[j]\)视作\(k\),把\(r[j] * g[j]\)视作\(b\))。但是我们发现斜率\(k\)并不是单调的,所以传统的斜率优化就无法解决这个问题了。

这时就衍生出两种写法了,一种是用splay维护凸包,一种是用cdq分治处理转移,我们要介绍的是后者。

考虑分治

对于任意一个\(f[i]\),我们只要考虑到所有\(1 \le j \le i - 1\)对它的影响就行了,cdq分治擅长处理这类问题。

对于一段区间\([l, r]\),先递归左子区间\([l, m]\),保证\([l, m]\)的\(f\)和\(g\)值都已经得到了;把左子区间按\(k\)递增排序,把右子区间按\(x\)递增排序,就可以按平时的斜率优化来\(O(n)\)转移;再把右子区间按在原序列中的位置递增排序,然后递归右子区间,此时左子区间对右子区间的影响都已经被考虑完了;边界是\(l == r\),到这里我们可以发现\(1\)到\(i - 1\)对\(i\)的影响都已经被考虑过了,别忘了\(f[i - 1]\)到\(f[i]\)的转移。

这样做是\(O(n (\log n) ^ 2)\)的,让人有点不爽,事实上我们可以做到\(O(n \log n)\)。

怎样做到1个\(\log\)

事实上cdq分治本身是一个归并的过程,我们可以利用这个过程去掉排序的复杂度。

我们希望拿到\([l, r]\)这个区间的时候\(x\)是单调的,于是在外面把原序列按\(x\)递增排序;拿到一个\(x\)递增的区间后,我们希望在原序列中靠左的东西去到左子区间,于是我们把\([l, r]\)扫一遍,把在原序列中位置\(\le m(m = l + r >> 1)\)的东西放左边,\(\ge m\)的放右边,而且左右子区间对于\(x\)的单调性没有受到影响;我们要处理左边对右边的影响,于是先递归左子区间,再像平时一样斜率优化处理转移,然后递归右子区间;我们希望一个区间的左子区间递归回来的时候是对于\(k\)单调递增的,于是在最后对\(k\)做一遍归并排序。这样每一层递归是\(O(n)\)的。

奉上蒟蒻的大常数代码。

  1. //written by newbiechd
  2. #include <iostream>
  3. #include <iomanip>
  4. #include <algorithm>
  5. #define R register
  6. #define I inline
  7. #define D double
  8. using namespace std;
  9. const int N = 100003;
  10. const D eps = 1e-8;
  11. int q[N];
  12. D f[N], g[N];
  13. struct cash {
  14. int id;
  15. D a, b, r, x;
  16. cash() {}
  17. cash(int id, D a, D b, D r) : id(id), a(a), b(b), r(r), x(b / a) {}
  18. I int operator < (cash q) { return x != q.x ? x < q.x : id < q.id; }
  19. }p[N], b[N];
  20. I D cross(int u, int v) { return (p[u].r * g[p[u].id] - p[v].r * g[p[v].id]) / (g[p[v].id] - g[p[u].id]); }
  21. I D calc(int u, int v) { return g[p[u].id] * (p[v].x + p[u].r); }
  22. I void update(int u, D v) {
  23. if (f[p[u].id] < v)
  24. f[p[u].id] = v, g[p[u].id] = f[p[u].id] / (p[u].b + p[u].r * p[u].a);
  25. }
  26. void solve(int l, int r) {
  27. if (l == r) {
  28. update(l, f[p[l].id - 1]);
  29. return ;
  30. }
  31. R int m = (l + r) >> 1, i, h, t;
  32. for (h = l, t = m + 1, i = l; i <= r; ++i)
  33. p[i].id <= m ? b[h++] = p[i] : b[t++] = p[i];
  34. for (i = l; i <= r; ++i)
  35. p[i] = b[i];
  36. solve(l, m), h = 1, t = 0;
  37. for (i = l; i <= m; ++i) {
  38. while (h < t && cross(q[t], i) < cross(q[t - 1], i) + eps)
  39. --t;
  40. q[++t] = i;
  41. }
  42. for (; i <= r; ++i) {
  43. while (h < t && calc(q[h], i) < calc(q[h + 1], i) + eps)
  44. ++h;
  45. update(i, calc(q[h], i) * p[i].a);
  46. }
  47. solve(m + 1, r);
  48. for (h = l, t = m + 1, i = l; h <= m && t <= r; )
  49. g[p[h].id] < g[p[t].id] ? b[i++] = p[h++] : b[i++] = p[t++];
  50. while (h <= m)
  51. b[i++] = p[h++];
  52. while (t <= r)
  53. b[i++] = p[t++];
  54. for (i = l; i <= r; ++i)
  55. p[i] = b[i];
  56. }
  57. int main() {
  58. ios::sync_with_stdio(0);
  59. R int n, i;
  60. D a, b, r;
  61. cin >> n >> f[1];
  62. for (i = 1; i <= n; ++i)
  63. cin >> a >> b >> r, p[i] = cash(i, a, b, r);
  64. g[1] = f[1] / (p[1].r * p[1].a + p[1].b), sort(p + 1, p + n + 1),
  65. solve(1, n), cout << fixed << setprecision(3) << f[n];
  66. return 0;
  67. }

[NOI2007]货币兑换 cdq分治,斜率优化的更多相关文章

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

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

  2. BZOJ1492:[NOI2007]货币兑换 (CDQ分治+斜率优化DP | splay动态维护凸包)

    BZOJ1492:[NOI2007]货币兑换 题目传送门 [问题描述] 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和B纪念券(以下简称B券).每个持有金券的 ...

  3. [BZOJ1492] [NOI2007] 货币兑换Cash(cdq分治+斜率优化)

    [BZOJ1492] [NOI2007] 货币兑换Cash(cdq分治+斜率优化) 题面 分析 dp方程推导 显然,必然存在一种最优的买卖方案满足:每次买进操作使用完所有的人民币:每次卖出操作卖出所有 ...

  4. 【uoj#244】[UER #7]短路 CDQ分治+斜率优化dp

    题目描述 给出 $(2n+1)\times (2n+1)$ 个点,点 $(i,j)$ 的权值为 $a[max(|i-n-1|,|j-n-1|)]$ ,找一条从 $(1,1)$ 走到 $(2n+1,2n ...

  5. bzoj1492[NOI2007]货币兑换Cash cdq分治+斜率优化dp

    1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 5541  Solved: 2228[Submit][Sta ...

  6. BZOJ 1492: [NOI2007]货币兑换Cash [CDQ分治 斜率优化DP]

    传送门 题意:不想写... 扔链接就跑 好吧我回来了 首先发现每次兑换一定是全部兑换,因为你兑换说明有利可图,是为了后面的某一天两种卷的汇率差别明显而兑换 那么一定拿全利啊,一定比多天的组合好 $f[ ...

  7. bzoj3672/luogu2305 购票 (运用点分治思想的树上cdq分治+斜率优化dp)

    我们都做过一道题(?)货币兑换,是用cdq分治来解决不单调的斜率优化 现在它放到了树上.. 总之先写下来dp方程,$f[i]=min\{f[j]+(dis[i]-dis[j])*p[i]+q[i]\} ...

  8. BZOJ 3963 HDU3842 [WF2011]MachineWorks cdq分治 斜率优化 dp

    http://acm.hdu.edu.cn/showproblem.php?pid=3842 写的check函数里写的<但是应该是<=,调了一下午,我是个zz. 就是普通的斜率优化因为有两 ...

  9. BZOJ4700 适者(贪心+cdq分治+斜率优化)

    首先考虑怎么安排攻击顺序.显然如果攻击了某台兵器就应该一直连续攻击直到将其破坏,破坏所需时间可以直接算出来,设其为b.假设确定了某个破坏顺序,如果交换相邻两个兵器,显然不会对其他兵器造成影响,两种顺序 ...

随机推荐

  1. asp.net 一般处理程序接收上传文件的问题

    在使用Html+ashx处理文件上传时,遇到上传文件超过4M的问题,首先HTML代码如下: <!DOCTYPE html> <html> <head> <me ...

  2. SQL语句还原数据库并移动文件到指定路径

    用SQL语句还原数据库时如果不指定数据库文件的存储路径,则默认把数据文件和日志文件存放到与原数据库相同的文件路径中,这样可能会产生错误,比如执行下面的语句: restore database Smar ...

  3. [翻译] CNPPopupController

    CNPPopupController CNPPopupController is a simple and versatile class for presenting a custom popup ...

  4. UNIX高级环境编程(7)标准IO函数库 - 二进制文件IO,流定位,创建临时文件和内存流

    1 二进制IO(Binary IO) 在前一篇我们了解了逐字符读写和逐行读写函数. 如果我们在读写二进制文件,希望以此读写整个文件内容,这两个函数虽然可以实现,但是明显会很麻烦且多次循环明显效率很低. ...

  5. 工作总结 [all]

    2. 工作总结 3. 面试经验 4. 其他

  6. zabbix 监控wind登录状态

    参考博文:http://blog.51cto.com/qicheng0211/1694583 需求:监控win 2008 的用户登录状态,无论用户登录成功与否都要告警(也可以刷选指定用户.指定时间内) ...

  7. Maven实战系列文章目录

    Maven实战(一)安装与配置 Maven实战(二)构建简单Maven项目 Maven实战(三)Eclipse构建Maven项目 Maven实战(四)生命周期 Maven实战(五)坐标详解 Maven ...

  8. Nodejs Redis 全部操作方法

    安装  npm install redis --save demo var redis = require('redis'); var client = redis.createClient('637 ...

  9. echarts中datazoom相关配置

    dataZoom=[ //区域缩放 { id: 'dataZoomX', show:true, //是否显示 组件.如果设置为 false,不会显示,但是数据过滤的功能还存在. backgroundC ...

  10. UVa 11440 - Help Tomisu(欧拉函数 + 问题转换)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...