低买高卖(2021-TRN1-C)
(由于参考了题解就没有交~)
题目大意
传送门
考虑股票市场,一共有n天。
对于第i天,B君知道股票的价格是每单位ai元
在每一天,B君可以选择买入一个单位的股票,卖出一个单位的股票,或者什么都不做。
刚开始B君有无穷多的钱,但是没有任何股票。
问n天之后B君最多可以赚多少钱。
(1 <= n <= 200000)
(1 <= ai <= 10000)
(注意:一天不可以同时买同时卖)
题目分析
题解的意思大概如下:
比如说对于1 4 10这个序列
最大利润肯定是10-1(但是编程时我们一眼是看不到最大的几个数和最小的几个数的,贪心去找会超时),那么我们就先用优先队列维护股价min值,
1.如果读到一个比min要大的数据,就计入到总利润中,popmin值,然后push两次该数据入队
2.否则直接push该数据进入优先队列
这样做可行。在1 4 10 这个例子中,我们可以认为,10-1被拆成了4-1 + 10-4。4被push进去,又被pop出来,相当于上没有用到4,但是这样可以在线性时间内实现算法。
那么为什么还要push两次呢?push的第二次是防止之后该数字成为了min值,会用到它。
代码
#include<bits/stdc++.h>
using namespace std;
priority_queue<int,vector<int>,greater<int> > q;
///https://www.cnblogs.com/sz-wcc/p/11620480.html参考链接
int main()
{
int n;
scanf("%d",&n);
int num;
int sum=0;
while(n--)
{
scanf("%d",&num);
if(!q.empty()&&num>q.top())
{
sum+=num-q.top();
q.pop();
q.push(num);
q.push(num);
}
else
{
q.push(num);
}
}
printf("%d\n",sum);
return 0;
}