HDU6438 - Buy and Resell (2018ccpc Network Competition) Greed + Priority Queue

Keywords: less

Every place can buy a thing or sell a thing or do nothing; ask the shortest time when the maximum profit and maximum profit are used.
Ideas: greedy, with a priority queue structure to save what was prepared to buy (but not yet bought), and encountered a minimum value of a lot less than the heap, then dropped the top element pop (which is the beginning of the transaction), and added the current value to the team two times. Why is it two?
Since the choice of the current value is not necessarily the best choice, there may be a better choice later, so the first time is used as an intermediate position to deposit in order to carry out further larger profit transactions.
The second is to store the current value as a carry-on item, which may be traded later (but the value previously traded as an intermediate position has also been traded).
Because the title also asked the shortest time required, so use a map to store each element as the total number of intermediate elements, when the total number of times is not 0, the element does not add time to queue (because it is only an intermediate element).
The code is as follows: (Note that the priority queue becomes a small root heap and must be submitted in G++, otherwise it will compile errors...)

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
//Greed plus priority queue: buy low and sell high;
int main()
{
    int i,j;
    int t;
    int n;
    ll now;
    ll ans;
    int cnt;
    scanf("%d",&t);
    while(t--)
    {
        priority_queue< ll,vector<ll>,greater<ll> >q;
        map<ll,int>mp;//Used to record the number of times the current element is used as an intermediary buying and selling position
        mp.clear();//Avoid uninitialized space in containers
        while(!q.empty())
        {
            q.pop();
        }
        ans=0;
        cnt=0;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%lld",&now);
            if(!q.empty()&&now>q.top())
            {
                int tp=q.top();
                ans+=now-tp;
                cnt++;
                q.pop();
                q.push(now);
                q.push(now);
                if(mp[tp]!=0)//That is to say, the top element is the middle of the sale of other elements, not the real sale.
                {
                    cnt--;
                    mp[tp]--;
                }
                mp[now]++;//now is temporarily the middle position, mp + +;
            }
            else
            {
                q.push(now);
            }
        }
        printf("%lld %d\n",ans,cnt<<1);//cnt is multiplied by 2 because the transaction is counted once.
    }
    return 0;
}

Posted by supratwinturbo on Sat, 05 Oct 2019 04:37:32 -0700