zoukankan      html  css  js  c++  java
  • Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake 线段树维护dp

    D. Babaei and Birthday Cake

    题目连接:

    http://www.codeforces.com/contest/629/problem/D

    Description

    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 .

    Sample Input

    2
    100 30
    40 10

    Sample Output

    942477.796077000

    Hint

    题意

    有n个蛋糕,然后第i个蛋糕只能放在地上或者放在体积和编号都比他小的上面

    然后问你体积最多能堆多大?

    题解:

    用线段树维护DP

    显然这个东西和lis(最长上升子序列)有一点像

    我们首先把每个东西的体积都离散化一下,然后我们选取比他小的最大值,然后进行更新就好了

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+6;
    typedef double SgTreeDataType;
    struct treenode
    {
      int L , R  ;
      double sum;
      int num;
      void updata(SgTreeDataType v)
      {
        sum += v;
      }
    };
    
    treenode tree[500000];
    
    inline void push_down(int o)
    {
    
    }
    
    inline void push_up(int o)
    {
        tree[o].sum = max(tree[2*o].sum , tree[2*o+1].sum);
    	if(tree[2*o].sum>tree[2*o+1].sum)
            tree[o].num=tree[2*o].num;
        else
            tree[o].num=tree[2*o+1].num;
    }
    
    inline void build_tree(int L , int R , int o)
    {
    	tree[o].L = L , tree[o].R = R,tree[o].sum = 0;
    	tree[o].num = L;
    	if (R > L)
    	{
    		int mid = (L+R) >> 1;
    		build_tree(L,mid,o*2);
    		build_tree(mid+1,R,o*2+1);
    	}
    }
    inline void updata2(int QL,int QR,SgTreeDataType v,int o)
    {
    	int L = tree[o].L , R = tree[o].R;
    	if (QL <= L && R <= QR)
        {
            tree[o].sum=max(tree[o].sum,v);
        }
    	else
    	{
    		push_down(o);
    		int mid = (L+R)>>1;
    		if (QL <= mid) updata2(QL,QR,v,o*2);
    		if (QR >  mid) updata2(QL,QR,v,o*2+1);
    		push_up(o);
    	}
    }
    inline SgTreeDataType query(int QL,int QR,int o)
    {
        if(QR<QL)return 0;
    	int L = tree[o].L , R = tree[o].R;
    	if (QL <= L && R <= QR) return tree[o].sum;
    	else
    	{
    		push_down(o);
    		int mid = (L+R)>>1;
    		SgTreeDataType res = 0;
    		if (QL <= mid) res = max(query(QL,QR,2*o),res);
    		if (QR > mid) res = max(query(QL,QR,2*o+1),res);
    		push_up(o);
    		return res;
    	}
    }
    
    
    double h[maxn],r[maxn],v[maxn];
    const double pi = acos(-1.0);
    vector<double>V;
    map<double,int> H;
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lf%lf",&r[i],&h[i]),v[i]=pi*r[i]*r[i]*h[i];
            V.push_back(v[i]);
        }
        sort(V.begin(),V.end());
        V.erase(unique(V.begin(),V.end()),V.end());
        for(int i=0;i<V.size();i++)
            H[V[i]]=i+1;
        build_tree(1,n,1);
        for(int i=1;i<=n;i++)
        {
            double p = v[i]+query(1,H[v[i]]-1,1);
            updata2(H[v[i]],H[v[i]],p,1);
        }
        printf("%.12f
    ",tree[1].sum);
        return 0;
    }
  • 相关阅读:
    day36 08-Hibernate抓取策略:批量抓取
    day36 07-Hibernate抓取策略:many-to-one上的抓取策略
    day36 06-Hibernate抓取策略:set集合上的抓取策略
    day36 05-Hibernate检索方式:离线条件查询
    day36 04-Hibernate检索方式:多表连接查询
    day36 03-Hibernate检索方式:排序、参数绑定、投影查询
    【收集】11款Linux数据恢复工具
    【收集】11款Linux数据恢复工具
    7个免费的Linux FTP客户端工具
    7个免费的Linux FTP客户端工具
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5205814.html
Copyright © 2011-2022 走看看