HDU 6438

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 (T250), indicating the number of test cases. For each test case:
The first line has an integer n. (1n105)
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. (1ai109)
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
Hint
In the first case, he will buy in 1, 2 and resell in 3, 4. profit = - 1 - 2 + 10 + 9 = 16 In the second case, he will buy in 2 and resell in 4. profit = - 5 + 10 = 5 In the third case, he will do nothing and earn nothing. profit = 0
 

 

Source
 
看完大佬题解  我又捋了下思路
 
首先保证最大的利润,并且可以多次买进,那么买和卖的次数相同,并且只要后面有比该物品价格高的,我就买这件物品,到后面我卖掉
 
也就是说  每件物品的价格i,对于0~i之间  ,我只要有比i小的价格就要进行交易
 
同时注意要利润最大,,那么我就要不停维护着0~i之间的最小值
 
理所当然的想到优先队列 对于i,每次和前面的最小值匹配完后,最小值出队列,那么价格i要不要进队列呢??
 
如果不进那万一后面还有更大的价格怎么办  比如2 8 10,
 
所以i也要进,就像这个例子,(8-2)+(10-8)=10-2;相当于在8处,买了又卖了,等于没有交易
 
那么还有交易次数,照着上面例子,交易次数肯定会多
 
注意到变多的原因是因为中间变量8  所以可以记录是否有这个中间变量,如果有,则这个交易次数就要减一
 
上代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    for(int Case=1;Case<=t;Case++)
    {
        int n;
        scanf("%d",&n);
        priority_queue<int , vector<int>,greater<int> >pq;//优先队列从小到大排, 
        long long ans=0,cnt=0;
        map<int,int>vis;//用来标记是否有中间变量 
        for(int i=0;i<n;i++)
        {
            int x;
            scanf("%d",&x);
            pq.push(x);
            if(pq.top() < x)//如果前面最小值比这个数小 
            {
                cnt++;//进行交易 
                ans+=x-pq.top();
                if(vis[pq.top()] > 0)//判断是否是中间变量 
                {
                    cnt--;
                    vis[pq.top()]--;
                }
                pq.pop();
                pq.push(x);
                vis[x]++;//代表在以后的交易中  该数为中间变量 
            }
        }
        printf("%lld %lld\n",ans,cnt*2);
    }
    return 0;
}

 

 

posted @ 2018-08-27 10:10  踩在浪花上  阅读(252)  评论(0编辑  收藏  举报