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

       题意是有n个城市,有一个商人想通过买卖一种物品来获利,在这n个城市中,每个城市对这个物品的价格是不一样的,商人每到一个城市时,可以选择买这个物品或者卖这个物品,或者不买不卖,最后通过尽量少的交易次数来获得最大的利润,输出最大利润和交易次数。注:刚开始商人没有物品,且本金充足。

       这道题和Codeforces上的一道题差不多,只是多了要求输出交易次数,对于这道题应该怎么贪心,可以先去看一下这篇博客:传送门。然后这道题就剩下怎么处理交易次数的问题了,在每次买入的时候将交易数++就好了,因为交易次数要尽量少,那么我们就让中间的变换次数尽量达到最大就好了,所以需要用一个标记数组(我用了map),用来标记每次买入时的物品的价格,相当于有1,2,3种价格本来是买1卖2再卖3,现在是买1,不买不卖2,卖3,前者就会有两次交易数,后者就只有一次(标记的作用就体现在这里),看代码吧,感觉挺好理解又不好理解...


AC代码:

题目来源:2018中国大学生程序设计竞赛 - 网络选拔赛 1001

#include <bits/stdc++.h>
#define ll long long
using namespace std;
priority_queue<int, vector<int>,greater<int> > q;
map<int,int> ma;
int n,T;
ll ans,num;

void init(){
	ans = num = 0;
	ma.clear();
	while(!q.empty())q.pop();
}

int main()
{
	scanf("%d",&T);
	while(T--){
		init();
		scanf("%d",&n);
		for(int i=0;i<n;i++){
			int x;
			scanf("%d",&x);
			if(q.empty() || x <= q.top()){
				q.push(x);
			}
			else{
				int index = q.top();q.pop();
				ans += (x - index);
				num++;
				if(ma[index] != 0){
					num--;
					ma[index]--;
				}
				q.push(x);
				q.push(x);
				ma[x]++;
			}
		}
		printf("%lld %lld\n",ans,num * 2);
	}
	return 0;
}