Codeforces 1374E1


1374E1. Reading Books (easy version)

题意

Alice和Bob一起读书

每个人需要至少读 k 本自己喜欢的书

每本书都具有三个属性,读完需要的时间、Alice是否喜欢、Bob是否喜欢

问最少需要花费的时间,或者说不存在读书方案


限制

Time limit per test: 2 seconds

Memory limit per test: 256 megabytes

1≤k≤n≤2⋅105

1≤ti≤104

0≤ai,bi≤1




贪心阅读书籍,将书籍分为四种类型——都喜欢、仅A喜欢、仅B喜欢、都不喜欢

对于都不喜欢的书,不需要进行考虑

将剩余三种类型的书籍按照时间从小到大的顺序排序(优先队列,也可分为三个数组sort)

每次处理都让两人剩余需要选择的数量减一

如果存在都喜欢的书籍,则判断是两个人读同一本喜欢的书花费的时间少,还是分开读各自喜欢的书花费的时间少,将时间较少的情况加入答案

如果不存在都喜欢的书,则只能分开读各自喜欢的书

如果过程中出现“不存在都喜欢的书,且仅A喜欢、仅B喜欢的书不都存在”,输出 -1




完整程序

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

int main()
{
    int n,k,t,a,b;
    ll ans=0;
    priority_queue<int,vector<int>,greater<int> > q[3]; //小顶堆优先队列
    
    scanf("%d%d",&n,&k);
    
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d%d",&t,&a,&b);
        if(a&&b)
            q[0].push(t); //都喜欢读
        else if(a&&!b)
            q[1].push(t); //a喜欢读
        else if(!a&&b)
            q[2].push(t); //b喜欢读
    }
    
    while(!q[0].empty()&&k>0) //先处理两个人都喜欢的书
    {
        if(!q[1].empty()&&!q[2].empty())
        {
            if(q[0].top()<=q[1].top()+q[2].top()) //如果两个人读同一本喜欢的书,时间比分开读各自喜欢的书小
            {
                ans+=q[0].top(); //就读同一本喜欢的书
                q[0].pop();
            }
            else
            {
                ans+=q[1].top()+q[2].top(); //否则分开读各自喜欢的书
                q[1].pop();
                q[2].pop();
            }
        }
        else //没法分开读,只能读同一本喜欢的书
        {
            ans+=q[0].top();
            q[0].pop();
        }
        k--;
    }
    
    while(!q[1].empty()&&!q[2].empty()&&k>0) //分开读各自喜欢的书
    {
        ans+=q[1].top()+q[2].top();
        q[1].pop();
        q[2].pop();
        k--;
    }
    
    if(!k) //如果已经读了k本书,表示存在答案
        printf("%lld
",ans);
    else //不存在答案
        puts("-1");
    
    return 0;
}

原文地址:https://www.cnblogs.com/stelayuri/p/13206990.html