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;
}