题意
传送门 Codeforces 865D
题解
按时间顺序用小根堆维护可买入的股价,每次贪心地取当前时间之前最小的股价以满足获利最大,此时获利为 y − x y-x y−x。但全局最优解中当前时间不一定是卖出,也可能是买入,那么把当前的股价信息 y y y 也用堆维护。若之后选择买入先前卖出的 y y y,那么此次获利为 ( z − y ) + ( y − x ) = z − x (z-y)+(y-x)=z-x (z−y)+(y−x)=z−x,那么需要将 y y y 再次用堆维护。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define maxn 300005
typedef long long ll;
struct node
{
int f, p, id;
bool operator<(const node &b) const
{
return p > b.p;
}
};
int N, P[maxn];
int main()
{
scanf("%d", &N);
for (int i = 0; i < N; ++i)
scanf("%d", P + i);
priority_queue<node> q;
ll res = 0;
for (int i = 0; i < N; ++i)
{
if (q.empty() || q.top().p >= P[i])
{
q.push(node{0, P[i], i});
}
else
{
node t = q.top();
q.pop();
res += P[i] - t.p;
q.push(node{1, P[i], i});
if (t.f)
q.push(node{0, P[t.id], t.id});
}
}
printf("%lld", res);
return 0;
}