codeforces867E&&865DBuy low Sell hig

版权声明:我这么弱的蒟蒻,虽然博文不是很好,但也请标明转发地址喵! https://blog.csdn.net/ACerAndAKer/article/details/82792543

贪心好题

我们首先要明确的一个贪心思想就是尽可能的低价买入,高价卖出,这样能获得最大利润,如何实现?
我们有两种情况是不能卖出的:第一种是它之前没有比他小的价格 ,那么卖这个 会比之前的优,所以要选择买这个,第二种是它之前的已经操作完了,就是之前没有可以操作的天了,这时也要选择买或不买,但不能卖,于是我们得到了初步想法,维护每天之前的最小值,然后每次比较当前的价格与之前的价格,然后进行操作,然后我们发现,遇到能卖就卖貌似不是最优的,可能存在后面一天卖出去会获得更大利润,所以我们要想一个方法,来使得可以抵消掉当前的卖出
然后就有了一个神奇的操作,我们用优先队列维护之前的最小值,然后对于能卖出的一天,我们先卖出,然后放两个当前价格到队列里,为什么呢?假如我们存在一个序列1 2 5,显然1买入,5卖出最优,但是按照之前的操作,会在2的时候卖出,然后我们看若在2的时候卖出,然后把两个2加入到队列里,现在ans=1,到5的时候,队列里有两个2,我们发现5可以卖出2,于是ans+=5-2=4,也是最优解,而队列里还有一个2,发现相当于跳过了2,用5卖出了1,为什么?
想一想过程,ans+(2-1)+(5-2)=ans+(5-1)这次买入2和之前卖出2抵消了,还剩一个待处理的2,在队列里,等人去用,然后这道题就解决了

代码

//By AcerMo
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lli long long int
using namespace std;
priority_queue<int,vector<int>,greater<int> >q;
int n;
inline int read()
{
	int x=0;char ch=getchar();
	while (ch>'9'||ch<'0') ch=getchar();
	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x;
}
signed main()
{
	n=read();lli ans=0,x;
	for (int i=1;i<=n;i++)
	{
		x=read();
		if (!q.size()||x<=q.top()) q.push(x);
		else ans+=(x-q.top()),q.pop(),q.push(x),q.push(x);
	}
	cout<<ans;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/ACerAndAKer/article/details/82792543
今日推荐