Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake(dp + BIT)

解决一个算法问题,通过动态规划和二进制索引树优化,寻找给定蛋糕集合中可堆叠的最大体积。

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






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值