题意:
给定
n
n
n天的股票价格,每天你可以选择买入一支股票或者卖出一支股票或者什么也不干,问能够得到的最大利润值为多少?输出最大利润值和达到该利润值需要的最少交易次数。
思路:
思路类似于一道经典的贪心题夹克老爷的逢三抽一
用优先队列来维护股票的状态。
对于第 i i i天的股票,如果前 i − 1 i-1 i−1天的股票价格都不小于当天的股票价格,那么这一天什么也不做
否则找到一个价格最低的买入,同时留下一个反悔的选项,即将当天的股票价格插入两次,则:
第一次出队列,假设出对列的股票价格为B,则类似于买入A卖出B,然后买入B卖出C,等价于买入A卖出C
第二次出队列,则代表真正买入。
此题得解。
时间复杂度: O ( T n l o g n ) O(Tnlogn) O(Tnlogn)
代码:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef pair<ll, int> P;
priority_queue<P, vector<P>, greater<P> > que;
int main(){
int T, n;
scanf("%d", &T);
while (T--) {
while (!que.empty()) que.pop();
scanf("%d", &n);
ll ans = 0, cnt = 0, x = 0;
for (int i = 1; i <= n; i++) {
scanf("%I64d", &x);
if (!que.empty() && x > que.top().first) {
P u = que.top(); que.pop();
if (u.second == 2) cnt += 2;
ans += x - u.first;
que.push(make_pair(x, 1));
}
que.push(make_pair(x, 2));
}
printf("%I64d %I64d\n", ans, cnt);
}
return 0;
}