HDU 6438 Buy and Resell (优先队列 or 贪心)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/PK__PK/article/details/82292406

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6438

题意:一个奸商在倒卖石油,对于每个城市都有不同的石油的价格,当奸商按顺序到达某个城市之后,他可以有3种操作:

1.买一个石油

2.卖一个石油

3.什么都不做的走开

现在按顺序给出每个城市的石油价格,求最大获利,和最少的交易次数。

题解:第一眼看到这个问题,觉得是个DP,想了半天没想出来,后来看题解才知道,是个贪心。

怎么贪心呢?

我们要求获利最大,所以必定低价买入高价卖出。但是我们会考虑到一个问题,就是什么时候卖?换句话说就是可能当前卖出买入价格最小的石油,获利也许不是最大。如 1  3 10这个样例,很明显在1的价格位置买入,3的价格卖出,是可以赚钱的,但是不是最优解。所以我们需要思考怎么“后悔”。

我们很容易可以发现加入 在 A地方买入 B地方卖出,再在B地方买入,在C地方卖出。其实等价于 A地方买入 C地方卖出。用样例解释一波:

还是1 3 10这个样例。我们在1价格买入,3价格卖出,获利2.再以3价格买入,然后在10价格卖出,获利7.把获利加起来就是9,实际上等同于在1价格买入,在10价格卖出。

这个先卖出,再次买入就是我们的“后悔”操作。

具体实现如下:

对于当前城市的价格比我最小值小的,就意味着我们在这城市没有获利,我们低价买入。

对于当前城市的价格比我最小值大的,就意味着我们在这城市卖出会有获利,我们选择卖出买入的最小值。并且记录我们获利的多少。为了我们能后悔我们选择再次以当前价格买入。我们要买两次,为什么要买两次的。首先我们第一次表明我们是以当前价格卖出,若以后还能有更优值,就可以把这个卖出去。这就是卖出再买入然后在卖出的操作。对于这样的操作我们实际上只需要记录为一次交易即可,即最初的买和最后的卖。相当于我加了个跳板。那么第二次就表明。我们是以这个价格买入的。就可以在后面将他卖出。因为若便利到这个价格就以为,你之前的最小值已经在更优的位置被卖出去了,现在才是最小值。

所以实际上我们就是对手中持有的石油进行了分类。跳板or非跳板,卖出跳板时次数不变,卖出非跳板时次数+2.手中持有的石油用优先队列维护。

这个题还是蛮难理解的(也行是我太菜)希望这篇详细的博客能给大家启发。

代码如下:

#include<bits/stdc++.h>
using namespace std;
const int mx = 1e5+5;

struct node{ 
	int val,type; // type表示分类 0 表示跳板, 2 表示非跳板 
	bool operator <(const node b) const{
		if(val != b.val) return val > b.val;  // 按照权值从小到大 
		return type > b.type; // 按照类型从小到大。 
	}
};

priority_queue<node> Q;
int main(){
	int z;
	scanf("%d",&z);
	while(z--){
		while(!Q.empty()) Q.pop();
		int n,sum = 0;
		long long ans = 0;
		node temp ;
		scanf("%d",&n);
		for(int i = 1 ; i <= n ; i ++){
			int val ;
			scanf("%d",&val);
			temp.val = val;
			temp.type = 2; // (非跳板)买入就是类型2 
			if(!Q.empty() && val > Q.top().val){ // 若当前能赚钱就买出最小值 
				ans += val - Q.top().val; //统计获利 
				sum += Q.top().type; // 为什么type是0 和2呢 0表示无效交易,2表示有效交易 。 
				temp.type = 0;  
				Q.pop();
				Q.push(temp); //加入两次,当中后悔药使用。 
				temp.type = 2;
				Q.push(temp);
			}
			else
			 	Q.push(temp);
		}
		printf("%lld %d\n",ans,sum);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/PK__PK/article/details/82292406