CodeForces - 867E Buy Low Sell High (贪心 +小顶堆)

https://vjudge.net/problem/CodeForces-867E

题意

一个物品在n天内有n种价格,每天仅能进行买入或卖出或不作为一种操作,可以同时拥有多种物品,问交易后的最大利益。

分析

贪心的取,当然是低买高卖。当买卖的顺序需要斟酌。考虑用小顶堆(优先队列)来维护这过程,我们每次得到一个新的价格,将其和堆顶的价格比较,如果比堆顶的价格低,就直接放入堆中,如果比堆顶的价格高,就意味着我们可以提前以堆顶的价格买入一个物品,然后以当前价格卖出,因此我们可以算出本次收益加到总收益中,这样我们就要将堆顶pop掉,然后将本次价格push两次入堆,push两次是因为我们若以堆顶的价格买入,不一定最终是以当前价格卖出的,当前价格有可能只是我们贪心的一个跳板,例如价格1,2,3,10,如果我们以1买入,2卖出,3买入,10卖出我们只能获得8,然而如果我们以1买入,10卖出,2买入,3卖出就可以获得10,我们贪心的过程中肯定会1买入2卖出,而这次2卖出只是我们10卖出的跳板,并不一定是非要在2卖出。

因此将某价格加入两次的作用分别是:

1.做中间价

2.做所有可能买入价中的一个(就和比堆顶低的价格直接扔入堆中一样的作用)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <set>
#include <bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define ms(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
#define eps 0.0000000001
#define IOS ios::sync_with_stdio(0);cin.tie(0);
#define random(a, b) rand()*rand()%(b-a+1)+a
#define pi acos(-1)
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const int inf = 0x3f3f3f3f;
const int maxn = 100000 + 10;
const int maxm = 200000 + 10;
const int mod = 1e9+7;

priority_queue<int,vector<int>,greater<int> >q;
int main(){
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
#endif
    int n;
    scanf("%d",&n);
    int x;
    ll ans=0;
    for(int i=0;i<n;i++){
        scanf("%d",&x);
        if(!q.empty()&&q.top()<x){
            ans+=x-q.top();
            q.pop();
            q.push(x);
        }
        q.push(x);
    }
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/fht-litost/p/9545309.html