HDU 7170 Package Delivery

Package Delivery

贪心 优先队列

题意

- 有n个包裹,每个包裹有自己的到达日期和截止日期
- 某肥宅能一次拿k个包裹,一天内可取多次,没有限制
- 问如何安排能够使得取包裹的次数最少

思路

在ddl之前取包裹的收益一定不如ddl时,因为这时会有更多送达的包裹
也就是说,只有当有包裹ddl到了我们才会去取包裹,我们也不需要取完当时到达的所有包裹,就先取k个ddl最小的包裹,当然也不定有k个那就能取几个取几个
这个贪心策略挺好想的,可惜比赛时没想到用优先队列

代码

    #define fst std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout << std::fixed << std::setprecision(20)
    #define le "\n"
    #define ll long long 
    #include <bits/stdc++.h>
    using namespace std;
    const int N=2e5+50;
    const int mod=998244353;

    struct Node{
        int l,r;
    };

    struct cmp1{
        bool operator () (const Node & a,const Node & b) const
        {
            return a.r>b.r;
        }
    };

    bool cmp(Node x,Node y){
        if(x.l==y.l) return x.r<y.r;
        return x.l<y.l;
    }

    void solve(){
        int n,k; cin>>n>>k;
        vector<Node> a(n);
        for(auto &i : a) cin>>i.l>>i.r;
        sort(a.begin(),a.end(),cmp);//对包裹进行排序,按照到达日期升序
        priority_queue<Node,vector<Node>,cmp1> que;
        
        que.push(a[0]);
        int ans = 0;
        int day = a[0].r;
        
        for(int i=1;i<n;){
            while(i<n&&a[i].l<=day||day==-1){
                if(day==-1) day = a[i].r;
                day = min(day,a[i].r);
                que.push(a[i]);
                i++;
            }
            if(!que.empty()){
                ans++;
                if(que.size()<=k){
                    while(!que.empty()) que.pop();
                    day = -1;
                }
                else{
                    int tmp=k;
                    while(tmp--) que.pop();//取k个包裹,其他不用急着取,因为越晚取收益越大
                    day = que.top().r;
                }
            }
        }
        ans += (que.size()+k-1)/k; //最后不一定全部取完,对剩余的包裹向上取整求次数
        cout<<ans<<le;
    }

    int main() {
        fst;
        int t; cin>>t;
        while(t--){
            solve();
        }
        return 0;
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值