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;
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章