Buy and Resell
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 480 Accepted Submission(s): 114
Problem Description
The Power Cube is used as a stash of Exotic Power. There are n cities numbered 1,2,…,n where allowed to trade it. The trading price of the Power Cube in the i-th city is ai dollars per cube. Noswal is a foxy businessman and wants to quietly make a fortune by buying and reselling Power Cubes. To avoid being discovered by the police, Noswal will go to the i-th city and choose exactly one of the following three options on the i-th day:
1. spend ai dollars to buy a Power Cube
2. resell a Power Cube and get ai dollars if he has at least one Power Cube
3. do nothing
Obviously, Noswal can own more than one Power Cubes at the same time. After going to the n cities, he will go back home and stay away from the cops. He wants to know the maximum profit he can earn. In the meanwhile, to lower the risks, he wants to minimize the times of trading (include buy and sell) to get the maximum profit. Noswal is a foxy and successful businessman so you can assume that he has infinity money at the beginning.
Input
There are multiple test cases. The first line of input contains a positive integer T (T≤250), indicating the number of test cases. For each test case:
The first line has an integer n. (1≤n≤105)
The second line has n integers a1,a2,…,an where ai means the trading price (buy or sell) of the Power Cube in the i-th city. (1≤ai≤109)
It is guaranteed that the sum of all n is no more than 5×105.
Output
For each case, print one line with two integers —— the maximum profit and the minimum times of trading to get the maximum profit.
Sample Input
3 4 1 2 10 9 5 9 5 9 10 5 2 2 1
Sample Output
16 4 5 2 0 0
题意:
有n天,每天都有一个股票价格ai,你每天可以花ai买下当天的股票,也可以以ai价格卖掉你手中的股票(但是最多只能卖一张或者买一张,且不能又买又卖,可以不买不卖) 求最大收益,且在最大收益情况下最小操作次数
题解:
为什么大家都说这道题出烂了啊,为什么我从来没见过啊,可能我是zz吧
这道题就是求一个收益最高且最短的合法括号序列,左括号表示当天买入,右括号表示当天卖出
开两个优先队列,其中一个存每一对括号,按照右括号的值排序,顶端最小,另一个优先队列存单独的左括号,仍然按照值排序,顶端最小
这样对于当前第i天的股票ai,有三种决策:①和顶端的单一左括号匹配成为一对括号;②最顶端的一对括号中,将右括号替换成当前这个括号,并将原来的右括号单独拉出来作为一个单一的左括号;③作为单一的左括号
每次都选收益最大的,搞定
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<math.h>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
#define LL long long
#define mod 1000000007
typedef struct Res
{
int x, y;
bool operator < (const Res &b) const
{
if(y>b.y)
return 1;
return 0;
}
}Res;
Res now, temp;
priority_queue<Res> q, q2;
int main(void)
{
LL ans;
int T, n, i, val, s1, s2, cnt;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
for(i=1;i<=n;i++)
{
s1 = s2 = 0;
scanf("%d", &val);
if(q.empty()==0)
s1 = val-q.top().y;
if(q2.empty()==0)
s2 = val-q2.top().y;
if(s1<=0 && s2<=0)
{
now.y = val;
q.push(now);
}
else if(s2>=s1)
{
now = q2.top();
q2.pop();
temp = now;
now.y = val;
q2.push(now);
q.push(temp);
}
else
{
now = q.top();
q.pop();
now.x = now.y;
now.y = val;
q2.push(now);
}
}
ans = cnt = 0;
while(q2.empty()==0)
{
ans += q2.top().y-q2.top().x;
cnt += 2;
q2.pop();
}
while(q.empty()==0)
q.pop();
printf("%lld %d\n", ans, cnt);
}
return 0;
}