zoukankan      html  css  js  c++  java
  • 「题解」[BZOJ 3728] Final Zarowki

    提供一种不用堆的做法.

    考虑贪心, 对于一个房间, 选择不小于它所需功率且功率最小的灯泡一定是最优的, 因为这样子能够最大程度的利用灯泡, 同时对 ({w_i}) 从大到小排序, 这样可以使功率大的灯泡浪费的更少.

    对每一个房间寻找不小于它所需功率且功率最小的灯泡, 将答案加上灯泡功率, 然后删去这个灯泡. 如果找不到, 则代表需要换一次灯泡, 并记录下换灯泡的次数 (t).

    最后对每个房间过剩的功率 (即这个房间灯泡的功率减去这个房间的所需功率) 进行从大到小排序, 将答案减去前 (k-t) 个值, 即可得到答案.

    特别地, 如果 (t) 大于 (k), 则表示这是一种无解状态, 输出 NIE

    因此我们需要维护一组数据, 要进行以下操作:

    • 插入一个数 (x)
    • 删除一个数 (x)
    • 寻找不小于数 (x) 且最小的数

    发现以上操作可以用平衡树解决, 由于此题空间较紧, 同时考虑代码难度等多方面因素, 可以使用 ( exttt{STL::set}) 代替平衡树完成以上操作.

    时间复杂度 (Theta(n log n)).

    #define ll long long
    #define it std::multiset<int>::iterator
    
    using std::multiset;
    
    const int N = 5e5;
    
    int n, flag, tot, p[N + 10], w[N + 10], qaq[N + 10];
    ll ans;
    
    multiset<int> s;
    
    bool cmp(int x, int y) { return x > y; }
    
    signed main() {
        cin >> n >> k;
        for (int i = 1; i <= n; i++) cin >> p[i], s.insert(p[i]);
        for (int i = 1; i <= n; i++) cin >> w[i];
        std::sort(w + 1, w + 1 + n);
        for (int i = n; i; i--) {
            int x = w[i];
            it tmp = s.upper_bound(x - 1);
            if (tmp == s.end())
                ans += x, flag++;
            else
                ans += *tmp, qaq[++tot] = *tmp - x, s.erase(tmp++);
        }
        if (flag > k) return cout << "NIE" << endl, 0;
        std::sort(qaq + 1, qaq + 1 + tot, cmp);
        for (int i = 1; i <= k - flag; i++) ans -= qaq[i];
        return cout << ans << endl, 0;
    }
    
  • 相关阅读:
    PHP-循环结构-数组
    PHP-数据类型-运算符
    数据库-mysql语句-查-WEB服务器
    数据库-mysql语句-查
    数据库-SQL语句:删除和修改语句-列类型-列约束
    软件工程-生命周期
    网络电视精灵
    小型资源管理器
    动态生成控件 并设置只能输入数字 和小数点
    C#七大原则
  • 原文地址:https://www.cnblogs.com/Aestas16/p/bzoj-3728.html
Copyright © 2011-2022 走看看