cf - 629D Babaei and Birthday Cake(DP+線段樹維護)

D - Babaei and Birthday Cake
Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u
Appoint description: 

Descriptionnode

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

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.ide

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.ui

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

Inputspa

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

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.rest

Outputcode

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.orm

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

Input
2
100 30
40 10
Output
942477.796077000
Input
4
1 1
9 7
1 4
10 7
Output
3983.539484752

 

Hint

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 12 and 4.


題意:找到累計最多的蛋糕體積。兩個蛋糕累計條件(j < i && v[j] < v[i])。

思路:能夠用最長上升子序列的 dp 來作,體積爲數列元素。 可是數據太大,查詢 j = 1 到 j < i 時須要浪費 O(n)的時間。時間複雜度就是 O(n^2) 確定會TEL。所以查詢以及更新利用線段樹來維護。將區間的從小到大抽象成體積 v[i] 從小到大,每次利用線段樹查詢和更新 dp[i]便可。時間複雜度爲 O(n*logn)。

代碼:

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cmath>
 5 using namespace std;
 6 
 7 struct Node{
 8     int l,r;
 9     long long Max;
10 }node[100005*4];
11 long long v[100005];
12 long long x[100005];
13 long long dp[100005];
14 const double PI = acos(-1.0);
15 
16 void build(int id,int l,int r){
17     int mid = (l+r)>>1;
18     node[id].l = l;
19     node[id].r = r;
20     if(l == r){
21         node[id].Max = 0;
22         return ;
23     }
24     build(id*2,l,mid);
25     build(id*2+1,mid+1,r);
26 
27     node[id].Max = max(node[id*2].Max,node[id*2+1].Max);
28 }
29 
30 void update(int id,int k,long long p){     //更新 k 處的值爲 p
31     int ll = node[id].l;
32     int rr = node[id].r;
33     int mid = (ll+rr)>>1;
34 
35     if(ll == rr){
36         node[id].Max = p;
37         return ;
38     }
39 
40     if(k <= mid)    update(id*2,k,p);
41     else
42         update(id*2+1,k,p);
43     node[id].Max = max(node[id*2].Max,node[id*2+1].Max);
44 }
45 
46 long long query(int id,int l,int r){
47     int ll = node[id].l;
48     int rr = node[id].r;
49     int mid = (ll+rr)>>1;
50 
51     if(l > r) return 0;
52 
53     if(ll== l && rr == r)
54         return node[id].Max;
55     else if(r <= mid)
56         return query(id*2,l,r);
57     else if(l > mid)
58         return query(id*2+1,l,r);
59     else
60         return max(query(id*2,l,mid),query(id*2+1,mid+1,r));
61 }
62 int main()
63 {
64     int n;
65     while(cin>>n){
66         long long r,h;
67         for(int i = 1;i <= n;i ++){
68             scanf("%I64d%I64d",&r,&h);
69             v[i] = r*r*h;
70             dp[i] = v[i];
71             x[i] = v[i];
72         }
73         sort(x+1,x+n+1);
74         long long ans = 0;
75         build(1,1,n);
76         for(int i = 1;i <= n;i ++){
77             int cur = lower_bound(x+1,x+n+1,v[i]) - x;      //前閉後開區間找大於或等於 v[i]的第一個位置。
78                                                             //wa了很久都不知道爲啥。
79             dp[i] = max(dp[i],query(1,1,cur-1)+v[i]);
80             update(1,cur,dp[i]);
81             ans = max(ans,dp[i]);
82         }
83         printf("%.15f\n",ans*PI);
84     }
85     return 0;
86 }
View Code
相關文章
相關標籤/搜索