2018CCPC网络赛1001:Buy and Resell(优先队列)

博客围绕1到n个城市物品交易问题展开,每个城市物品有对应价值,可买、卖或不操作。解题思路是维护优先队列,比较当前队列最小值与城市物品价值,若小则假设卖出并将该城市价值加入队列两次。同时为计算最小交易次数,加入物品时打标记,优先卖二手物品,还给出了AC代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

题目大意:

1到n每个城市有一个价值为a[i]的物品,当你到达这个城市的时候,可以花费a[i]买一个物品,也可以卖掉手中一个物品获得a[i],也可以什么都不做。问最后能够获得的最大利润是多少,最大利润相同时求最少的交易次数,同一时刻手中可以持有多个物品。

 

解题思路:

维护一个优先队列,每次到达一个城市,判断一下当前优先队列中最小的值是否小于当前城市的a[i],如果小于的话,就假设在这里将它卖掉,同时将这个城市的a[i]加入优先队列,注意这个时候需要加入两次,第一次是因为对于最小的我们可以选择不在这里交易而选择在后面某个城市交易,这样的话只是以这个城市为中转。第二次就是正常的将这个城市的物品加入优先队列。

这里注意题目需要我们计算最小次数,那么我们就可以往优先队列里面加入物品的时候打上标记,将二手的标记为1,卖出物品的时候价值相同时优先卖二手的即可。

 

Ac代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
const int mod=1e9+7;
typedef long long ll;
struct node
{
    int val,flag;   //flag为1标记为二手
    node(int val,int flag):val(val),flag(flag) {}
    bool operator<(const node &p) const
    {
        if(val==p.val) return flag<p.flag;  //价值相同 二手优先级高
        return val>p.val;
    }
};
int n,x;
ll res,ans;
priority_queue<node> que;
int main()
{
    int QAQ;
    scanf("%d",&QAQ);
    while(QAQ--)
    {
        res=0,ans=0;    //利润以及次数
        scanf("%d",&n);
        while(!que.empty()) que.pop();
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            if(!que.empty())
            {
                node now=que.top();
                if(now.val<x)   //队列中最小的小于a[i]
                {
                    que.pop();res+=1LL*x-now.val;   //计算利润
                    if(now.flag==0) ans++;  //如果卖掉的是一手的 ans++
                    que.push(node(x,0));
                    que.push(node(x,1));
                }
                else que.push(node(x,0));
            }
            else que.push(node(x,0));
        }
        printf("%lld %lld\n",res,ans*2);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值