zoukankan      html  css  js  c++  java
  • Codeforces 629D.( Babaei and Birthday Cake)

    D. Babaei and Birthday Cake
     

    As you know, every birthday party has a cake! This time, Babaei is going to prepare the very special birthday party's cake.

    Simple cake is a cylinder of some radius and height. The volume of the simple cake is equal to the volume of corresponding cylinder. Babaei has n simple cakes and he is going to make a special cake placing some cylinders on each other.

    However, there are some additional culinary restrictions. The cakes are numbered in such a way that the cake number i can be placed only on the table or on some cake number j where j < i. Moreover, in order to impress friends Babaei will put the cake i on top of the cake j only if the volume of the cake i is strictly greater than the volume of the cake j.

    Babaei wants to prepare a birthday cake that has a maximum possible total volume. Help him find this value.

    Input

    The first line of the input contains a single integer n (1 ≤ n ≤ 100 000) — the number of simple cakes Babaei has.

    Each of the following n lines contains two integers ri and hi (1 ≤ ri, hi ≤ 10 000), giving the radius and height of the i-th cake.

    Output

    Print the maximum volume of the cake that Babaei can make. Your answer will be considered correct if its absolute or relative error does not exceed 10 - 6.

    Namely: let's assume that your answer is a, and the answer of the jury is b. The checker program will consider your answer correct, if .

    Examples
    input
    2
    100 30
    40 10
    output
    942477.796077000
    input
    4
    1 1
    9 7
    1 4
    10 7
    output
    3983.539484752
    Note

    In first sample, the optimal way is to choose the cake number 1.

    In second sample, the way to get the maximum volume is to use cakes with indices 1, 2 and 4.

    题意:做蛋糕,给出N个半径,和高的圆柱,要求后面的体积比前面大的可以堆在前一个的上面,求最大的体积和。

    思路:dp,以当前的体积为当前最上层的最大值,dp[i]=max(dp[j])+tiji[i](j<i&&tiji[i]>tiji[j]);

    由于这样时间复杂度为N*N,所以想到离散化体积,然后用线段树去维护区间最大值,lisan[i]为离散化后体积对应的值,那么要查[1,lisan[i]-1];这保证了体积比当前值小,

    线段树保存在区间以某个点为最上的最大值,由于按顺序来,所以顺序要求以保证。复杂度N*(logN)2;

      1 #include<stdio.h>
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<string.h>
      5 #include<queue>
      6 #include<stack>
      7 #include<math.h>
      8 #include<iomanip>
      9 using namespace std;void update(int k);
     10 int cmp(const void*p,const void*q);
     11 long long  query(int l,int r,int n,int m,int id);
     12 void build(int l,int r,int id);
     13 const double pi=acos(-1);
     14 long long tree[5*100005];
     15 struct node
     16 {
     17     int id;
     18     long long tiji;
     19 };
     20 node dian[100005];
     21 long long  dui[100005];
     22 int lisan[100005];
     23 int dibu[100005];
     24 int main(void)
     25 {
     26     int i,j,k;long long p,q;
     27     //freopen("data.in","r",stdin);
     28     //freopen("wrong.out","w",stdout);
     29     while(scanf("%d",&k)!=EOF)
     30     {   memset(tree,0,sizeof(tree));
     31         long long  maxx=0;
     32         for(i=1;i<=k;i++)
     33         {
     34             scanf("%I64d %I64d",&p,&q);
     35            dian[i].tiji=p*p*q;
     36            dian[i].id=i;
     37         }
     38         qsort(dian+1,k,sizeof(node),cmp);
     39         int ans=1;lisan[dian[1].id]=ans;dui[dian[1].id]=dian[1].tiji;
     40         for(i=2;i<=k;i++)
     41         {
     42             if(dian[i].tiji!=dian[i-1].tiji)
     43                 ans++;
     44             lisan[dian[i].id]=ans;
     45             dui[dian[i].id]=dian[i].tiji;
     46         }build(1,ans,0);
     47         for(i=1;i<=k;i++)
     48         {
     49             long long  tt=query(1,lisan[i]-1,1,ans,0);
     50            long long  mn=tt+dui[i];
     51             if(mn>maxx)
     52             {
     53                 maxx=mn;
     54             }
     55             if(mn>tree[dibu[lisan[i]]])
     56             {   tree[dibu[lisan[i]]]=mn;
     57                 update(dibu[lisan[i]]);
     58             }
     59         }long double MN=1.0*maxx*pi;
     60        cout<<setprecision(9)<<MN<<endl;
     61     }return 0;
     62 }
     63 int cmp(const void*p,const void*q)
     64 {
     65     node*nn=(node*)p;
     66     node*mm=(node*)q;
     67     return nn->tiji>mm->tiji?1:-1;
     68 }
     69 void build(int l,int r,int id)
     70 {
     71     if(l==r)
     72     {
     73         dibu[l]=id;
     74     }
     75     else
     76     {
     77         build(l,(l+r)/2,2*id+1);
     78         build((l+r)/2+1,r,2*id+2);
     79     }
     80 }
     81 long long query(int l,int r,int n,int m,int id)
     82 {   if(r==0)return 0;
     83     if(l>m||r<n)
     84     {
     85         return 0;
     86     }
     87     else if(l<=n&&r>=m)
     88     {
     89         return tree[id];
     90     }
     91     else
     92     {   long long  x;long long  y;
     93         x=query(l,r,n,(n+m)/2,2*id+1);
     94         y=query(l,r,(n+m)/2+1,m,2*id+2);
     95         return max(x,y);
     96     }
     97 }
     98 void update(int k)
     99 {
    100     int ss=(k-1)/2;
    101     while(ss>=0)
    102     {
    103         tree[ss]=max(tree[2*ss+1],tree[2*ss+2]);
    104         if(ss==0)
    105                break;
    106         ss=(ss-1)/2;
    107     }
    108 }
      1 #include<stdio.h>
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<string.h>
      5 #include<queue>
      6 #include<stack>
      7 #include<math.h>
      8 #include<iomanip>
      9 using namespace std;
     10 int cmp(const void*p,const void*q);
     11 long long  query(int l,int r,int n,int m,int id);
     12 void  update(int l,int r,int nn,int mm,int k,long long cc);
     13 const double pi=acos(-1);
     14 long long tree[5*100005];
     15 struct node
     16 {
     17     int id;
     18     long long tiji;
     19 };
     20 node dian[100005];
     21 long long  dui[100005];
     22 int lisan[100005];
     23 int main(void)
     24 {
     25     int i,j,k;long long p,q;
     26     //freopen("data.in","r",stdin);
     27     //freopen("wrong.out","w",stdout);
     28     while(scanf("%d",&k)!=EOF)
     29     {   memset(tree,0,sizeof(tree));
     30         long long  maxx=0;
     31         for(i=1;i<=k;i++)
     32         {
     33             scanf("%I64d %I64d",&p,&q);
     34            dian[i].tiji=p*p*q;
     35            dui[i]=p*p*q;
     36            dian[i].id=i;
     37         }
     38         qsort(dian+1,k,sizeof(node),cmp);
     39         int ans=1;lisan[dian[1].id]=ans;dui[dian[1].id]=dian[1].tiji;
     40         for(i=2;i<=k;i++)
     41         {
     42             if(dian[i].tiji!=dian[i-1].tiji)
     43                 ans++;
     44             lisan[dian[i].id]=ans;
     45         }long long tt;
     46         for(i=1;i<=k;i++)
     47         { if(lisan[i]!=1)
     48            tt=query(1,lisan[i]-1,1,ans,0);
     49            else tt=0;
     50            long long  mn=tt+dui[i];
     51             if(mn>maxx)
     52             {
     53                 maxx=mn;
     54             }
     55         update(lisan[i],lisan[i],1,ans,0,mn);
     56         }
     57         double MN=1.0*maxx*pi;
     58       printf("%.9f
    ",MN);
     59     }return 0;
     60 }
     61 int cmp(const void*p,const void*q)
     62 {
     63     node*nn=(node*)p;
     64     node*mm=(node*)q;
     65     return nn->tiji>mm->tiji?1:-1;
     66 }
     67 long long query(int l,int r,int n,int m,int id)
     68 {
     69     if(l>m||r<n)
     70     {
     71         return 0;
     72     }
     73     else if(l<=n&&r>=m)
     74     {
     75         return tree[id];
     76     }
     77     else
     78     {   long long  x;long long  y;
     79         x=query(l,r,n,(n+m)/2,2*id+1);
     80         y=query(l,r,(n+m)/2+1,m,2*id+2);
     81         return max(x,y);
     82     }
     83 }
     84 
     85 void update(int l,int r,int nn,int mm,int k,long long cc)
     86 {
     87 
     88     if(l>mm||r<nn)
     89     {
     90         return ;
     91     }
     92     else if(l==nn&&r==mm)
     93     {
     94             tree[k]=max(cc,tree[k]);
     95         return ;
     96     }
     97     else
     98     {
     99         update(l,r,nn,(nn+mm)/2,2*k+1,cc);
    100         update(l,r,(nn+mm)/2+1,mm,2*k+2,cc);
    101         tree[k]=max(tree[2*k+1],tree[2*k+2]);
    102     }
    103 }
    不同的单点更新
    油!油!you@
  • 相关阅读:
    【题解】 bzoj1191: [HNOI2006]超级英雄Hero (二分图)
    谈谈Android项目框架的前世今生
    十四个好用的开源漏洞检测工具
    关于Java导出100万行数据到Excel的优化方案
    逗号分割符--字段中含逗号等情况的解析方法Java实现
    Java日期处理
    服务器&浏览器伪装的故事
    浏览器User-agent简史(user-agent)
    修改tomcat服务器banner的方法
    life_motto
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5208035.html
Copyright © 2011-2022 走看看