题目链接: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;
}