【题意】给定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);
}