cf 板刷日记(1600-1800)三

CF 865D D. Buy Low Sell High

tag: 反悔贪心,贪心,妙妙题

建一个最小堆,从前往后按照顺序,对每个值判断:

  1. 如果当前值比堆顶值还小,则直接放入堆中(注意放入堆中不是买)

  2. 如果当前值比堆顶值大,则把堆顶弹出(在当前为止卖掉)。会有一种情况,在当前为止卖掉不如留到之后再卖。

对于情况二,设堆顶值,当前值,之后的更优值分别为 \(p_1,p_2,p_3\)

则如果现在卖掉,且再以现在的价格买入一个,留到 \(p_3\) 卖掉:\((p_3-P_2)+(p_2-p_1)\)

和直接把 \(p_1\) 留到 \(p_3\) 卖一样。所以,在情况 2 的弹出堆顶后,可以再插入一个 \(p_2\)。注意,这个 \(p_2\) 不是情况 \(1\)\(p_2\),所以这里需要插入两个 \(p_2\)

虽然插入两个,但是和题意不冲突,因为第一个 \(p_2\) 实质上是一个虚拟的东西

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;

void solve(){
    int n;
    cin>>n;

    int ans=0;
    priority_queue<int,vector<int>,greater<int>> q;

    for(int i=1;i<=n;i++){
        int val;
        cin>>val;

        if(q.size() && val>q.top()){
            ans+=val-q.top();
            q.pop();
            q.push(val);
        }
        q.push(val);
    }

    cout<<ans;
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int ct=1;
    // cin>>ct;

    while(ct--){
        solve();
    }
}
posted @ 2026-03-16 22:03  LYET  阅读(2)  评论(0)    收藏  举报