cf 板刷日记(1600-1800)三
CF 865D D. Buy Low Sell High
tag: 反悔贪心,贪心,妙妙题
建一个最小堆,从前往后按照顺序,对每个值判断:
-
如果当前值比堆顶值还小,则直接放入堆中(注意放入堆中不是买)
-
如果当前值比堆顶值大,则把堆顶弹出(在当前为止卖掉)。会有一种情况,在当前为止卖掉不如留到之后再卖。
对于情况二,设堆顶值,当前值,之后的更优值分别为 \(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();
}
}

浙公网安备 33010602011771号