CF865D Buy Low Sell High

依靠堆完成贪心。

维护一个小根堆,扫描每一天的价格,如果之前的最小价格比它小就直接丢到堆里面去,如果比它大就累加答案并丢弃之前的最优解,然后把这个价格入队两次

考虑一下为什么要入队两次,一次就相当于在这一天购买,一次代表以后反悔,答案累加之后就相当于在之前丢弃掉的地方买入在新的地方卖出,这样子一定能计算到最优答案。

时间复杂度$O(nlogn)$。

Code:

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;

const int N = 3e5 + 5;

int n;
ll a[N], ans = 0;

struct Node {
    ll val;
    
    inline Node (ll v) {
        val = v;
    }
    
    friend bool operator < (const Node &x, const Node &y) {
        return x.val > y.val;    
    }
    
};
priority_queue <Node> Q;

template <typename T>
inline void read(T &X) {
    X = 0; char ch = 0; T op = 1;
    for(; ch > '9'|| ch < '0'; ch = getchar())
        if(ch == '-') op = -1;
    for(; ch >= '0' && ch <= '9'; ch = getchar())
        X = (X << 3) + (X << 1) + ch - 48;
    X *= op;
}

int main() {
    read(n);
    for(int i = 1; i <= n; i++) {
        read(a[i]);
        if(Q.empty()) Q.push(Node(a[i]));
        else {
            if(a[i] < Q.top().val) Q.push(Node(a[i]));
            else {
                ans += a[i] - Q.top().val; Q.pop();
                Q.push(Node(a[i])), Q.push(Node(a[i]));
            }
        }
    }
    
    printf("%lld\n", ans);
    return 0;
}
View Code

 还有几个奶牛排序题等我理清楚之后再更。

posted @ 2018-10-02 22:59  CzxingcHen  阅读(227)  评论(0编辑  收藏  举报