题目链接:Problem - 1374E1 - Codeforces
题意:
Alice 和 Bob 一共有 n 本书要读。第 i 本书有三个属性:阅读时间 ti(
(1≤ti≤1e4),ai(为 1 表示 Alice 喜欢这本书,为 0 表示 Alice 不喜欢),bi(为 1 表示 Bob 喜欢这本书,为 0 表示 Bob 不喜欢)。
他们需要从这些书中选择若干本,这些书中至少有 k 本是 Alice 喜欢的,至少有 k 本是 Bob 喜欢的。且阅读的总时间最小 (1≤k≤n≤2e5).,最终输出最小总的阅读时间,如果没有满足题目要求的方案,输出-1.
题解:
因为题目说至少有 k 本是 Alice 喜欢的,至少有 k 本是 Bob 喜欢的,所以当 Alice选了一本自己喜欢的书, Bob也一定会选一本自己喜欢的书。因此,我们可以用贪心的方法合并两人选书过程:将两个人单独喜欢的书分别排序,然后从小到大两两合并,然后当成他俩都喜欢的书,价格为这两本书的和。然后与两个人均喜欢的书的价格进行合并后排序。如果合并后两人均喜欢的书仍不足k,那么输出-1.如果满足k,则连续加k本排序后的书,最终结果为最小总的阅读时间。
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string.h>
#include<map>
#include<queue>
#include<vector>
#include<set>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
const ll mm = 2e5+ 60;
const int inf = 0x3f3f3f3f;
ll n, k, a, b, c, f1[mm], f2[mm], f3[mm],c1=0,c2=0,c3=0,ans=0;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> k;
for (int i = 1; i <= n; i++)
{
cin >> a >> b >> c;
if (b == 0 && c == 0) continue;
if (b == 0 && c == 1) f3[++c3] = a;
if (b == 1 && c == 0) f2[++c2] = a;
if (b == 1 && c == 1) f1[++c1] = a;
}
sort(f3 + 1, f3 + c3 + 1);
sort(f2 + 1, f2 + c2 + 1);
for (int i = 1; i <= min(c3, c2); i++)f1[++c1] = f3[i] + f2[i];
sort(f1 + 1, f1 + c1+ 1);
if (c1 < k) {
cout << -1;
return 0;
}
for (int i = 1; i <= k; i++) ans += f1[i];
cout << ans;
return 0;
}