Codeforces 629D.( Babaei and Birthday Cake)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 629D.( 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.
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.
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 .
2
100 30
40 10
942477.796077000
4
1 1
9 7
1 4
10 7
3983.539484752
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\n",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 }
以上是关于Codeforces 629D.( Babaei and Birthday Cake)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake(线段树+离散化优化DP)
codeforces#343 D. Babaei and Birthday Cake
Codeforces Round #629 (Div. 3)