• 【堆】B001_分级(大/小根堆分别维护升/降序序列)


    给定长度为N的序列A,构造一个长度为N的序列B,满足:

    1. B非严格单调,即B1≤B2≤…≤BN或B1≥B2≥…≥BN。
    2. 最小化 S=∑Ni=1|Ai−Bi|。
      只需要求出这个最小值S。

    输入格式
    第一行包含一个整数N。
    接下来N行,每行包含一个整数Ai。
    输出格式
    输出一个整数,表示最小S值。
    数据范围
    1≤N≤2000,
    0≤Ai≤109

    输入样例:
    7
    1
    3
    2
    4
    5
    3
    9
    输出样例:
    3
    

    方法一:大小根堆

    用小根堆维护一个降序的序列B和用大根堆维护一个升序的序列B,具体为:

    • 当维护一个升序序列时,当后面遍历到的元素x比大根堆maxQ的堆顶元素还要小的话,那就要对x做出调整,增量为 maxQ.top()-x
    • 当维护一个降序序列时,当后面遍历到的元素x比小根堆minQ的堆顶元素还要大的话,那也要对x做出调整,减量为 x-minQ.top()
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int main() {
        std::ios::sync_with_stdio(false);
        cin.tie(0);cout.tie(0);
        ll n, ans1=0, ans2=0; cin>>n;
        int A[n]; for (int i=0; i<n; i++) cin>>A[i];
        priority_queue<ll> maxQ;
        priority_queue<ll, vector<ll>, greater<int>> minQ;
    
        for (ll x : A) {      //维护升序序列
            maxQ.push(x);
            if (x<maxQ.top()) {
                ans1+=maxQ.top()-x; 
                maxQ.pop(), maxQ.push(x);
            }
        }
        for (ll x : A) {      //维护降序序列
            minQ.push(x);
            if (x>minQ.top()) {
                ans2+=x-minQ.top(); 
                minQ.pop(), minQ.push(x);
            }
        }
        cout << min(ans1, ans2);
        return 0;
    }
    

    复杂度分析

    • Time\(O(nlogn)\)
    • Space\(O(n)\)
  • 相关阅读:
    自己的思考
    spring MVC整合freemarker
    手把手教你搭建SpringMVC——最小化配置
    深入hibernate的三种状态
    maven 构建slf4j1.7.7之简单测试与源码解析
    maven 构建slf4j1.7.7之简单测试与源码解析
    (转)URI和URL的区别
    Spring缓存机制的理解
    (转)oracle 高水位线详解
    (转)PL/SQL Developer使用技巧、快捷键
  • 原文地址:https://www.cnblogs.com/wdt1/p/13630457.html
Copyright © 2020-2023  润新知