zoukankan      html  css  js  c++  java
  • [NOI2007]货币兑换Cash(DP+动态凸包)

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

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

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

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

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

    CODE:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<set>
     6 #include<cmath>
     7 using namespace std;
     8 const double esp=1e-7;
     9 const int maxn=101000;
    10 int dcmp(double a) {
    11     if (fabs(a)<esp) return 0;
    12     return a<0?-1:1;
    13 }
    14 struct node{
    15     double x,y,k;bool f;
    16     node(double _x,double _y):x(_x),y(_y),f(0){}
    17     node():f(0){}
    18     inline bool error(){return x>1e50;}
    19 }error(1e51,0);
    20 inline bool operator == (const node x,const node y) {return dcmp(x.x-y.x)==0;}
    21 inline bool operator < (const node x,const node y){
    22     if (x.f||y.f) return dcmp(x.k-y.k)>0;
    23     else return dcmp(x.x-y.x)<0;
    24 }
    25 inline double operator *(const node x,const node y) {return x.x*y.y-x.y*y.x;}
    26 inline node operator -(const node x,const node y){
    27     node tmp;
    28     tmp.x=x.x-y.x;tmp.y=x.y-y.y;
    29     return tmp;
    30 }
    31 inline double calc_k(node x,node y) {return (x.y-y.y)/(x.x-y.x);}
    32 set<node> gap;
    33 typedef set<node>::iterator iter;
    34 inline node lower(node x) {
    35    iter it=gap.lower_bound(x);
    36    return it==gap.end()?error:*it;
    37 }
    38 inline node next(node x) {
    39     iter it=gap.upper_bound(x);
    40     return it==gap.end()?error:*it;
    41 }
    42 inline node pre(node x) {
    43     iter it=gap.lower_bound(x);
    44     return it==gap.begin()?error:*(--it);
    45 }
    46 inline void ins(node a) {
    47     if (gap.empty()) {a.k=0;gap.insert(a);return;}
    48     node d1=pre(a),d2=lower(a);
    49     if (d1.error()&&d2.y>a.y) return ;
    50     if ((!d1.error())&&(!d2.error())&&(dcmp((d2-d1)*(a-d1))<=0)) return ;
    51     if (d2==a) return;
    52     node p1,p2=next(a);
    53     for (;;){
    54         p1=p2;p2=next(p2);
    55         if (p1.error()||p2.error()) break;
    56         if (dcmp((p1-a)*(p2-a))<=0) break;
    57         gap.erase(p1);
    58     }
    59     p2=pre(a);
    60     for (;;){
    61         p1=p2;p2=pre(p2);
    62         if (p1.error()||p2.error()) break;
    63         if (dcmp((p1-a)*(p2-a))>=0) break;
    64         gap.erase(p1);
    65     }
    66     d1=pre(a),d2=next(a);
    67     if (d1.error()) a.k=0;else a.k=calc_k(d1,a);gap.insert(a);
    68     if (!d2.error()) gap.erase(d2),d2.k=calc_k(a,d2),gap.insert(d2);
    69 }
    70 inline double get_k(double a,double b) {
    71     node tmp;tmp.f=1;tmp.k=-a/b;
    72     tmp=*(--gap.lower_bound(tmp));
    73     return a*tmp.x+b*tmp.y;
    74 }
    75 double a[maxn],b[maxn],r[maxn],na[maxn],nb[maxn],f[maxn];
    76 int main(){
    77     int n,s;
    78     scanf("%d%d",&n,&s);
    79     for (int i=1;i<=n;i++) scanf("%lf%lf%lf",a+i,b+i,r+i);
    80     f[1]=s;
    81     nb[1]=f[1]/(a[1]*r[1]+b[1]);
    82     na[1]=nb[1]*r[1];
    83     ins(node(na[1],nb[1]));
    84     for (int i=2;i<=n;i++) {
    85         f[i]=max(f[i-1],get_k(a[i],b[i]));
    86         nb[i]=f[i]/(a[i]*r[i]+b[i]);
    87         na[i]=nb[i]*r[i];
    88         ins(node(na[i],nb[i]));
    89     }
    90     printf("%.3f
    ",f[n]);
    91 }
    92     

      

  • 相关阅读:
    流程控制
    数据类型和运算符
    抽奖
    蓝桥杯 第五届
    python下编译py成pyc和pyo
    Django中提示TemplateDoesNotExist?
    Ubuntu16.04 apache2 wsgi 部署django
    Ubuntu 14.04下Django+MySQL安装部署全过程
    LVM原理及PV、VG、LV、PE、LE关系图
    SQLServer2008-镜像数据库实施手册(双机)SQL-Server2014同样适用
  • 原文地址:https://www.cnblogs.com/New-Godess/p/4354675.html
Copyright © 2011-2022 走看看