题目描述:
有一个物品,给你这个物品n天的价格,你可以在在第i天买进或卖出或者什么都不做,如何获得最大利益,假设本金是无限大的。
分析:
我们建立一个最小堆,即优先队列,每天,将队列的最小值和当前的值比较,如果最小值大于等于当前值,直接将当前值加入优先队列,否则,ans+=这两个数的差值,
**并将当前数加入到队列两次,加入队列两次的目的是:
1.当前价格并不一定是最终的卖出价格,可能后续还有更大的数置换它。
2.当前的天数还有可能买入并在后续卖出。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
#include <vector>
#include <set>
#include <map>
using namespace std;
const int maxn = 100000 + 10;
int a[maxn];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
priority_queue<int,vector<int>,greater<int> >Q;
map<int,int>q;
int n;
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
}
long long ans=0;
int num=0;
for(int i=1; i<=n; i++)
{
if(Q.empty()||Q.top()>=a[i])
{
Q.push(a[i]);
}
else
{
int t=Q.top();
Q.pop();
if(q[t]) q[t]--;
else num+=2;
ans+=(a[i]-t);
q[a[i]]++;
Q.push(a[i]);
Q.push(a[i]);
}
}
printf("%I64d %d\n",ans,num);
}
return 0;
}