zoukankan      html  css  js  c++  java
  • [CF629D] Babaei and Birthday Cake

    [CF629D] Babaei and Birthday Cake - dp,树状数组

    Description

    有n个圆柱形的蛋糕,已知它们的底面半径r和侧面高h。把这n个蛋糕叠起来,第i个蛋糕放在第j个蛋糕上面(1<=j<=i-1)的条件是第i个蛋糕的体积必须大于第j个蛋糕的体积。求叠放起来的蛋糕体积最大能是多少?

    Solution

    这里用传统的 LIS 二分答案方法维护的问题在于下标过大,因此有两种方法

    一种是用 map 维护,思路其实一样,大体代码类似这样

    auto l=mp.lower_bound(volume);
    int ans=(--l)->second+volume;
    auto r=++l;
    while(r!=mp.end() && r->second<=ans) ++r;
    mp.erase(l,r);
    mp[volume]=ans;
    

    另一种是绕开二分答案,按体积升序(相同则编号降序)排序后对编号做 LIS,这样可以用树状数组维护

    相同则编号降序是重要的,可以防止重复转移 (wa 37)

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    const int N = 2e5 + 5;
    
    // todo: binary index tree (max)        2'
    
    int bt[N];
    
    int lowbit(int x)
    {
        return x & (-x);
    }
    
    void add(int i, int x)
    {
        while (i < N)
            bt[i] = max(bt[i], x), i += lowbit(i);
    }
    
    int query(int i)
    {
        int ans = 0;
        while (i > 0)
            ans = max(ans, bt[i]), i -= lowbit(i);
        return ans;
    }
    
    // todo: dp main                        3'
    
    int f[N], n;
    
    struct item
    {
        int r, h, v, id;
        bool operator<(const item &rhs) const
        {
            if (v != rhs.v)
                return v < rhs.v;
            else
                return id > rhs.id; // wa 37
        }
    } a[N];
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        cin >> n;
        for (int i = 1; i <= n; i++)
        {
            cin >> a[i].r >> a[i].h;
            a[i].v = a[i].r * a[i].r * a[i].h;
            a[i].id = i;
        }
        sort(a + 1, a + n + 1);
    
        for (int i = 1; i <= n; i++)
        {
            int id = a[i].id, v = a[i].v;
            f[i] = query(id) + v;
            add(id, f[i]);
        }
    
        cout << fixed << setprecision(12) << *max_element(f + 1, f + n + 1) * 3.14159265358979 << endl;
    }
    
    
  • 相关阅读:
    洛谷P3400 仓鼠窝(单调栈)
    牛客练习赛65
    2015 HIAST Collegiate Programming Contest] 题解(AK)
    “科林明伦杯”哈尔滨理工大学第十届程序设计竞赛(同步赛)
    POJ 2421 Constructing Roads
    逆序数&&线段树
    HDU-1166 敌兵布阵 (线段树&&树状数组入门)
    Codeforces Round #484 (Div. 2)
    HDU
    HDU 5773 The All-purpose Zero (变形LIS)
  • 原文地址:https://www.cnblogs.com/mollnn/p/14618528.html
Copyright © 2011-2022 走看看