hdu 6438 Buy and Resell 优先队列贪心+思维

版权声明:本文为博主原创文章,转载请附上原博客链接。 https://blog.csdn.net/Dale_zero/article/details/82116168

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6438

k值为是否已经卖出的标记,若k=1,说明在该天曾经卖出一件物品。然而因为从a买入,从b卖出,再从b买入,从c卖出和从a买入,从c卖出的结果是一样的。所以定义k值用来更新买卖的最优值。在优先队列中,如果两元素w值(当天价值)相同,则优先取k较大的元素。

优先队列存储每一天的价格,贪心对于第i天的价格,取前i-1天最小的价格与之比较。若比当前值大,就直接将a【i】加入优先队列(堆)中。否则弹出队首元素,答案加上a【i】-前i-1天的最小值。接下来向优先队列中加入两个a【i】,k值分别为0和1。应为排序时k大的排在前面,所以不用担心“从a买入,从b卖出,再从b买入,从c卖出”会被计算两次的情况。

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define mod 1000000007
#define For(i,m,n) for(int i=m;i<=n;i++)
#define Dor(i,m,n) for(int i=m;i>=n;i--)
#define LL long long
#define lan(a,b) memset(a,b,sizeof(a))
#define sqr(a) a*a
using namespace std;

LL a[100010];

struct node
{
    LL w;
    int k;
};


    bool operator <(node a,node b)
    {
        if(a.w==b.w)
            return a.k<b.k;
        return a.w>b.w;
    }


int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        priority_queue <node> run;
        memset(a,0,sizeof a);
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]);
        LL ans=0,id=0;
        for(int i=1;i<=n;i++)
        {
            node a1;
            a1.w=a[i];
            a1.k=0;
            if(run.empty())
            {
                run.push(a1);
                continue;
            }
            //printf("w=%lld k=%d\n",run.top().w,run.top().k);
            if(run.top().w>=a[i])
                run.push(a1);
            else
            {
                node tem=run.top();
                run.pop();
                node temp;
                temp.w=a[i];
                temp.k=1;
                if(tem.k==1)
                {
                    run.push(temp);
                    temp.k=0;
                    run.push(temp);
                    ans+=a[i]-tem.w;
                }
                else
                {
                    run.push(temp);
                    temp.k=0;
                    run.push(temp);
                    ans+=a[i]-tem.w;
                    id+=2;
                }
            }
        }
        printf("%lld %lld\n",ans,id);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Dale_zero/article/details/82116168