​2018中国大学生程序设计竞赛 - 网络选拔赛 ​

A buy and resell

 

题意:给出n,n个地区商品的价格,从1走到n,每个地区只能选择:1、买一个,2、卖一个(之前有买的)3、不买也不买

思路:设置 买卖队列(优先队列小到大),若buy.top()<sell.top()<val[i],买下加上差价,num++。若sell.top()<val[i],把sell.top()买下,val[i]放入sell,若buy[i]<val[i]卖掉买下val[i] 放入sell,num++,不然就buy队列为空买下可能以后要用。在最后的时候把买下没用的处理掉。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int maxn=1e5+10;
priority_queue< int,vector<int>,greater<int> > buy,sell;
typedef long long ll;
//priority_queue 默认从大到小 修改后从小到大
ll val[maxn];
int main()
{
int n,t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%lld",&val[i]);
ll ans=0,cnt=0;//tiaixao????
for(int i=0;i<n;i++){
//cout<<ans<<endl;
if(buy.size()!=0&&sell.size()!=0&&buy.top()<sell.top()&&sell.top()<val[i]){
ans+=val[i];cnt++;
sell.push(val[i]);
buy.pop();
}
else if(sell.size()!=0&&sell.top()<val[i]){//交换
buy.push(sell.top());
sell.pop();
sell.push(val[i]);
ans+=val[i]-2*buy.top();
}
else if(buy.size()!=0&&buy.top()<val[i]) {
ans+=val[i];cnt++;//cout<<i<<endl;
sell.push(val[i]);
buy.pop();
}
else buy.push(val[i]),ans-=val[i];
}
while(buy.size()!=0){
ans+=buy.top();
buy.pop();
}
printf("%lld %lld\n",ans,cnt*2);

while(!buy.empty()) buy.pop();
while(!sell.empty()) sell.pop();

}

return 0;
}