CF867E Buy Low Sell High

\(ProblemLink\)

题目大意

你预言了每天的股票价格\(v_i\),从第\(1\)天开始,你每天可以选择卖一支股票,买一支
股票,或者什么也不做。问直到第\(n\)天结束你最多可以获得多少收益。

\(n\le3*10^5\)

思路分析

我们可以先把所有元素丢到小根堆里。

如果存在\(a_i>a_j(i>j)\)那么\(j\)这一天是显然要买股票的。

但是我们不知道是不是应该在第\(i\)天卖。

可能存在一个\(k>i,a_k>a_i\),那么在第\(i\)天卖了可能不优,也可能最优方案要在第\(i\)天买。

那么我们还是把利润累加到\(ans\),但是我们往堆中再丢一个\(a_i\),

这个时候如果你选择了这个\(a_i\),就相当于在\(i\)天不卖了,或者说把那个股票又买回来了。

这道题就这样快乐的解决了。

代码实现

/*
@Date    : 2019-09-06 22:27:00
@Author  : Adscn (adscn@qq.com)
@Link    : https://www.cnblogs.com/LLCSBlog
*/
#include<bits/stdc++.h>
#include<bits/extc++.h>
using namespace std;
#define IL inline
#define RG register
#define gi getint()
#define gc getchar()
#define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
template<typename T>IL bool chkmax(T &x,const T &y){return x<y?x=y,1:0;}
template<typename T>IL bool chkmin(T &x,const T &y){return x>y?x=y,1:0;}
IL int getint()
{
	RG int xi=0;
	RG char ch=gc;
	bool f=0;
	while(!isdigit(ch))ch=='-'?f=1:f,ch=gc;
	while(isdigit(ch))xi=xi*10+ch-48,ch=gc;
	return f?-xi:xi;
}
template<typename T>
IL void pi(T k,char ch=0)
{
	if(k<0)k=-k,putchar('-');
	if(k>=10)pi(k/10,0);
	putchar(k%10+'0');
	if(ch)putchar(ch);
}
typedef long long ll;
__gnu_pbds::priority_queue<ll,greater<ll> > Q;
int main(void)
{
	int n=gi;
	ll ans=0;
	for(int i=1;i<=n;++i)
	{
		ll x;
		cin>>x;
		Q.push(x);
		if(Q.top()<x){
			ans+=x-Q.top();
			Q.pop(),Q.push(x);
		}
	}
	pi(ans);
	return 0;
}
posted @ 2019-09-07 08:08  Adscn  阅读(689)  评论(0编辑  收藏  举报