【题意】给定N≤105个蛋糕,编号为1∼N,每个都有体积Vi ,任意一个蛋糕都可以放在桌子上,对于蛋糕对(i,j),i可以放在j上,当且仅当i>j且Vi≥Vj ,求能摆放的蛋糕的最大体积?
【解题方法】
dp[i]表示第i个蛋糕在最上面的最大体积和dp[i]=max{dp[j]}+Vi,j<i且Vj<Vi
考虑用BIT优化一下这个转移,离散化一下,记录当前体积蛋糕在最上面的最大体积和,然后就可以O(logn)转移了
ans=max{dp[i]},时间复杂度为O(nlogn)
//AC 代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=100010;
const double PI=acos(-1);
#define ll long long
ll v[maxn];
vector<ll>xs;
int lowbit(int x){
return x&(-x);
}
struct BIT{
int n;ll c[maxn];
void init(int _n){
n=_n;
memset(c,0,sizeof(c));
}
void add(int i,ll v){
while(i<=n){
c[i]=max(c[i],v);
i+=lowbit(i);
}
}
ll querymax(int i)
{
ll ret=0;
while(i>0){
ret=max(ret,c[i]);
i-=lowbit(i);
}
return ret;
}
}bit;
int main()
{
int r,h,n;
cin>>n;
xs.clear();
for(int i=1; i<=n; i++){
cin>>r>>h;
v[i]=1LL*r*r*h;
xs.push_back(v[i]);
}
ll ans=0;
sort(xs.begin(),xs.end());
xs.resize(unique(xs.begin(),xs.end())-xs.begin());
bit.init(xs.size());
for(int i=1; i<=n; i++){
int idx=lower_bound(xs.begin(),xs.end(),v[i])-xs.begin()+1;
ll cur=bit.querymax(idx-1)+v[i];
ans=max(ans,cur);
bit.add(idx,cur);
}
printf("%.12f\n",PI*ans);
}