CodeForces 867E Buy Low Sell High(優先隊列,貪心)

描述

You can perfectly predict the price of a certain stock for the next N days. You would like to profit on this knowledge, but only want to transact one share of stock per day. That is, each day you will either buy one share, sell one share, or do nothing. Initially you own zero shares, and you cannot sell shares when you don’t own any. At the end of the N days you would like to again own zero shares, but want to have as much money as possible.

Input

Input begins with an integer N (2 ≤ N ≤ 3·105), the number of days.

Following this is a line with exactly N integers p*1, *p*2, …, *p**N (1 ≤ p**i ≤ 106). The price of one share of stock on the i-th day is given by p**i.

Output

Print the maximum amount of money you can end up with at the end of N days.

input

9
10 5 4 7 9 12 6 2 10

output

20

input

20
3 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4

output

41

Note

In the first example, buy a share at 5, buy another at 4, sell one at 9 and another at 12. Then buy at 2 and sell at 10. The total profit is  - 5 - 4 + 9 + 12 - 2 + 10 = 20.

思路

你知道未來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 <bits/stdc++.h>
using namespace std;
#define mem(a, b) memset(a, b, sizeof(a))
typedef long long ll;
priority_queue<ll, vector<ll>, greater<ll>> q;
int main()
{
    //freopen("in.txt", "r", stdin);
    ll n, x;
    ll ans = 0;
    scanf("%lld", &n);
    for (ll i = 1; i <= n; i++)
    {
        scanf("%lld", &x);
        if (q.empty() || x <= q.top())
        {
            q.push(x);
        }
        else
        {
            ans += x - q.top();
            q.pop();
            q.push(x), q.push(x);
        }
    }
    printf("%lld\n", ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章