zoukankan      html  css  js  c++  java
  • Codeforces Round #343 (Div. 2) D

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

    思路:首先离散化蛋糕体积,以蛋糕数量建树建树,每个节点维护最大值,也就是假如节点i放在最上层情况下的体积最大值dp[i]。每次查询比蛋糕i小且最大体积的蛋糕,然后更新线段树。注意此题查询的技巧!!查询区间不变l,r,才能保证每次查到的是小且最大体积。

      1 #include<iostream>
      2 #include<string>
      3 #include<algorithm>
      4 #include<cstdlib>
      5 #include<cstdio>
      6 #include<set>
      7 #include<map>
      8 #include<vector>
      9 #include<cstring>
     10 #include<stack>
     11 #include<cmath>
     12 #include<queue>
     13 #define clc(a,b) memset(a,b,sizeof(a))
     14 #include <bits/stdc++.h>
     15 using namespace std;
     16 #define LL long long
     17 const int maxn = 1e5 + 10;
     18 const int inf=0x3f3f3f3f;
     19 const double pi=acos(-1);
     20 double dp[maxn];
     21 double v[maxn],f[maxn];
     22 int num[maxn];
     23 struct node
     24 {
     25     double r,h;
     26 } p[maxn];
     27 
     28 double V(node a)
     29 {
     30     return a.r*a.r*a.h*pi;
     31 }
     32 
     33 struct Node
     34 {
     35     int l,r;
     36     double maxx;
     37 } tree[100010*4];
     38 
     39 void pushup(int cnt)
     40 {
     41     tree[cnt].maxx=max(tree[cnt<<1].maxx,tree[cnt<<1|1].maxx);
     42 }
     43 
     44 void b_tree(int l,int r,int rt)
     45 {
     46     tree[rt].l=l;
     47     tree[rt].r=r;
     48     if(l==r)
     49     {
     50         tree[rt].maxx=0.0;
     51         return ;
     52     }
     53     int mid=(l+r)>>1;
     54     b_tree(l,mid,rt<<1);
     55     b_tree(mid+1,r,rt<<1|1);
     56     pushup(rt);
     57 }
     58 
     59 double query(int l,int r,int rt)
     60 {
     61     if(tree[rt].l>=l&&tree[rt].r<=r)
     62     {
     63         return tree[rt].maxx;
     64     }
     65     int mid=(tree[rt].l+tree[rt].r)>>1;
     66     double ans=0.0;
     67     if(l<=mid)
     68         ans=max(ans,query(l,r,rt<<1));
     69     if(r>mid)
     70         ans=max(ans,query(l,r,rt<<1|1));
     71     return ans;
     72 }
     73 
     74 void update(int x,double val,int rt)
     75 {
     76     if(tree[rt].l==x&&tree[rt].r==x)
     77     {
     78         tree[rt].maxx=max(tree[rt].maxx,val);
     79         return;
     80     }
     81     int mid=(tree[rt].l+tree[rt].r)>>1;
     82     if(x<=mid)
     83         update(x,val,rt<<1);
     84     else
     85         update(x,val,rt<<1|1);
     86     pushup(rt);
     87 }
     88 
     89 int main()
     90 {
     91     int n;
     92     while(cin>>n)
     93     {
     94         b_tree(1,n,1);
     95         clc(dp,0);
     96         for(int i=0; i<n; i++)
     97         {
     98             scanf("%lf%lf",&p[i].r,&p[i].h);
     99             v[i]=V(p[i]);
    100             f[i]=v[i];
    101         }
    102         sort(f,f+n);
    103         for(int i=0; i<n; i++)
    104         {
    105             num[i]=lower_bound(f,f+n,v[i])-f+1;
    106         }
    107         for(int i=0; i<n; i++)
    108         {
    109             if(num[i]-1==0)
    110                 dp[i]=v[i];
    111             else
    112                 dp[i]=query(1,num[i]-1,1)+v[i];
    113             update(num[i],dp[i],1);
    114         }
    115         double ans=0.0;
    116         for(int i=0; i<n; i++)
    117             ans=max(ans,dp[i]);
    118         printf("%.10f
    ",ans);
    119     }
    120     return 0;
    121 }
    View Code
  • 相关阅读:
    异常
    C++中的mutable,volatile,explicit关键字
    Vi配置文件--Vimrc
    结构体和类的区别
    [转]恢复视力的方法(500度以下)
    与struct相关的宏定义 ---今Tencent笔试用到的
    如何在C++中调用C的代码
    C中如何调用C++函数?
    技术博走起
    Shell常见命令实践
  • 原文地址:https://www.cnblogs.com/ITUPC/p/5212674.html
Copyright © 2011-2022 走看看