第一次打动态凸包维护dp,感觉学到了超级多的东西。

首先,set是如此的好用!!!可以通过控制一个flag来实现两种查询,维护凸包和查找斜率k

不过就是重载运算符和一些细节方面有些恶心,90行解决

后面还有一个cdq分治,找时间学下,看下能不能处理一大类恶心的问题

github还是不会用,找时间搞下吧

CODE:

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<set>
#include<cmath>
using namespace std;
const double esp=1e-;
const int maxn=;
int dcmp(double a) {
if (fabs(a)<esp) return ;
return a<?-:;
}
struct node{
double x,y,k;bool f;
node(double _x,double _y):x(_x),y(_y),f(){}
node():f(){}
inline bool error(){return x>1e50;}
}error(1e51,);
inline bool operator == (const node x,const node y) {return dcmp(x.x-y.x)==;}
inline bool operator < (const node x,const node y){
if (x.f||y.f) return dcmp(x.k-y.k)>;
else return dcmp(x.x-y.x)<;
}
inline double operator *(const node x,const node y) {return x.x*y.y-x.y*y.x;}
inline node operator -(const node x,const node y){
node tmp;
tmp.x=x.x-y.x;tmp.y=x.y-y.y;
return tmp;
}
inline double calc_k(node x,node y) {return (x.y-y.y)/(x.x-y.x);}
set<node> gap;
typedef set<node>::iterator iter;
inline node lower(node x) {
iter it=gap.lower_bound(x);
return it==gap.end()?error:*it;
}
inline node next(node x) {
iter it=gap.upper_bound(x);
return it==gap.end()?error:*it;
}
inline node pre(node x) {
iter it=gap.lower_bound(x);
return it==gap.begin()?error:*(--it);
}
inline void ins(node a) {
if (gap.empty()) {a.k=;gap.insert(a);return;}
node d1=pre(a),d2=lower(a);
if (d1.error()&&d2.y>a.y) return ;
if ((!d1.error())&&(!d2.error())&&(dcmp((d2-d1)*(a-d1))<=)) return ;
if (d2==a) return;
node p1,p2=next(a);
for (;;){
p1=p2;p2=next(p2);
if (p1.error()||p2.error()) break;
if (dcmp((p1-a)*(p2-a))<=) break;
gap.erase(p1);
}
p2=pre(a);
for (;;){
p1=p2;p2=pre(p2);
if (p1.error()||p2.error()) break;
if (dcmp((p1-a)*(p2-a))>=) break;
gap.erase(p1);
}
d1=pre(a),d2=next(a);
if (d1.error()) a.k=;else a.k=calc_k(d1,a);gap.insert(a);
if (!d2.error()) gap.erase(d2),d2.k=calc_k(a,d2),gap.insert(d2);
}
inline double get_k(double a,double b) {
node tmp;tmp.f=;tmp.k=-a/b;
tmp=*(--gap.lower_bound(tmp));
return a*tmp.x+b*tmp.y;
}
double a[maxn],b[maxn],r[maxn],na[maxn],nb[maxn],f[maxn];
int main(){
int n,s;
scanf("%d%d",&n,&s);
for (int i=;i<=n;i++) scanf("%lf%lf%lf",a+i,b+i,r+i);
f[]=s;
nb[]=f[]/(a[]*r[]+b[]);
na[]=nb[]*r[];
ins(node(na[],nb[]));
for (int i=;i<=n;i++) {
f[i]=max(f[i-],get_k(a[i],b[i]));
nb[i]=f[i]/(a[i]*r[i]+b[i]);
na[i]=nb[i]*r[i];
ins(node(na[i],nb[i]));
}
printf("%.3f\n",f[n]);
}

  

[NOI2007]货币兑换Cash(DP+动态凸包)的更多相关文章

  1. BZOJ 1492: [NOI2007]货币兑换Cash( dp + 平衡树 )

    dp(i) = max(dp(i-1), x[j]*a[i]+y[j]*b[i]), 0<j<i. x, y表示某天拥有的最多钱去买金券, 金券a和金券b的数量. 然后就很明显了...平衡 ...

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

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

  3. BZOJ1492: [NOI2007]货币兑换Cash 【dp + CDQ分治】

    1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 5391  Solved: 2181 [Submit][S ...

  4. [BZOJ1492] [NOI2007]货币兑换Cash 斜率优化+cdq/平衡树维护凸包

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

  5. 【BZOJ-1492】货币兑换Cash DP + 斜率优化 + CDQ分治

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

  6. bzoj千题计划237:bzoj1492: [NOI2007]货币兑换Cash

    http://www.lydsy.com/JudgeOnline/problem.php?id=1492 dp[i] 表示 第i天卖完的最大收益 朴素的dp: 枚举从哪一天买来的在第i天卖掉,或者是不 ...

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

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

  8. 【BZOJ1492】[NOI2007]货币兑换Cash 斜率优化+cdq分治

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

  9. 1492: [NOI2007]货币兑换Cash【CDQ分治】

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

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

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

随机推荐

  1. AppBarLayout学习笔记

    LinearLayout的子类 AppBarLayout要点: 功能:让子View(AppBar)可以选择他们自己的滚动行为. 注意:需要依赖CoordinatorLayout作为父容器,同时也要求一 ...

  2. C# 调用外部dll(转)

    C# 调用外部dll   一.      DLL与应用程序 动态链接库(也称为DLL,即为"Dynamic Link Library"的缩写)是Microsoft Windows最 ...

  3. Java编程思想非主流知识点

    1. Java中的多态性理解(注意与C++区分) Java中除了static方法和final方法(private方法本质上属于final方法,因为不能被子类访问)之外,其它所有的方法都是动态绑定,这意 ...

  4. handler的使用

    2014-04-15 10:45:06 简单学习了handler的使用. 昨天下载的问题,在手机上正常,在平板上不正常. 怀疑是网络的问题. 一直获得的流为空 2014-04-15 18:10:59 ...

  5. 一句话绑定父函数的作用域this

    //如何在返回的函数中绑定父函数的作用域this function bound () { return function () { console.log(this); }.bind(this); } ...

  6. 解callback嵌套

    function checkPassword(username,password,callback){ var pwdHash; var queryStr = 'select * from user ...

  7. shell读取文件的每一行

    写法一: ---------------------------------------------------------------------------- #!/bin/bash while ...

  8. db2 数据类型

    数据类型: 字符串类型 描述 CHARACTER(n) n bytes定长字符串. n 大于0 不大于255. 默认 1. VARCHAR(n) 变长字符串,最大 n bytes. n大于 0 小于表 ...

  9. 解剖 Elasticsearch 集群 - 之三

    解剖 Elasticsearch 集群 - 之三 本篇文章是一系列涵盖 Elasticsearch 底层架构和原型示例的其中一篇.在本篇文章中,我们会讨论 Elasticsearch 如何提供准实时搜 ...

  10. 添加redo日志组和添加日志组多元化

    查看redo日志组的状态和日志的位置. SQL> 没有被使用,所以切几次日志,组合4已生效. SQL> select * from v$log; GROUP#   THREAD#  SEQ ...