题意:给定n天,每天有个价格,可以买一个物品,可以把手中的物品卖掉,求最大利润和最少买卖次数。
思路:最大利润按这个https://blog.csdn.net/Dilly__dally/article/details/82055866思路求,先看第二个样例9 5 9 10 5 ,按队列模拟利润是 9-5 + 10-9 ,可以看出9是一个中间物,不用买9,所以只需在原来思路的基础上加上对入队和出队的访问就可以了,具体:因为数据到了1e9,不能用数组,所以用map<int,int> 来代替访问数组,每次要卖的时候就给mp[a]++(至于不能用0、1判断,因为可能会有多个相同的价格),如果对头的元素已经访问过(卖过),那么cnt--,对头的访问量也--。最后cnt要*2(因为cnt计算的是卖的次数,有卖肯定有买~)。
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn=200005;
const double eps=1e-8;
const double PI = acos(-1.0);
#define lowbit(x) (x&(-x))
map<int,int> mp;
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int t;
cin>>t;
int n;
while(t--)
{
priority_queue<int,vector<int>,greater<int> > pq;
mp.clear();
cin>>n;
ll ans=0,cnt=0;
for(int i=0;i<n;i++)
{
int a;
cin>>a;
if(!pq.empty()&&pq.top()<a)
{
int t=pq.top();
pq.pop();
pq.push(a);
cnt++;
ans+=(a-t);
if(mp[t]>0)
{
cnt--;
mp[t]--;
}
mp[a]++;
}
pq.push(a);
}
cout<<ans<<" "<<cnt*2<<endl;
}
return 0;
}