zoukankan      html  css  js  c++  java
  • 【堆】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)\)
  • 相关阅读:
    Lighting maps_练习二
    Lighting maps_练习一
    Materials_练习
    Basic Lighting_练习二
    *201809-3
    程序设计思维与实践 Week14 作业 (3/4/数据班)
    程序设计思维与实践 Week14 限时大模拟 (3/4/数据班)
    程序设计思维与实践 Week15 作业 (3/4/数据班)
    程序设计思维与实践CSP-M4补题
    CCF201609-3
  • 原文地址:https://www.cnblogs.com/wdt1/p/13630457.html
Copyright © 2011-2022 走看看