持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第31天,点击查看活动详情
【Codeforces】Codeforces Round #653 (Div. 3) E1. Reading Books | 贪心
题目链接
题目
Easy and hard versions are actually different problems, so read statements of both problems completely and carefully.
Summer vacation has started so Alice and Bob want to play and joy, but... Their mom doesn't think so. She says that they have to read some amount of books before all entertainments. Alice and Bob will read each book together to end this exercise faster.
There are n books in the family library. The i-th book is described by three integers: — the amount of time Alice and Bob need to spend to read it, (equals 1 if Alice likes the i-th book and 0 if not), and (equals 1 if Bob likes the ii-th book and 0 if not).
So they need to choose some books from the given nn books in such a way that:
- Alice likes at least k books from the chosen set and Bob likes at least k books from the chosen set;
- the total reading time of these books is minimized (they are children and want to play and joy as soon a possible).
The set they choose is the same for both Alice an Bob (it's shared between them) and they read all books together, so the total reading time is the sum of titi over all books that are in the chosen set.
Your task is to help them and find any suitable set of books or determine that it is impossible to find such a set.
题目大意
有 本书,第 本书有三个属性 分别代表阅读这本书需要的时间、Alice 喜不喜欢这本书( 是 1 表示喜欢,0 表示不喜欢)和 Bob 喜不喜欢这本书( 是 1 表示喜欢,0 表示不喜欢)。
选择若干本书,设选择的书的集合为 S,则需要满足以下要求:
在满足以上要求的情况下最小化 。
思路
一本只有 Alice 喜欢的书和一本只有 Bob 喜欢的书可以合并为一本他们两个都喜欢的书, 属性为两本书的 属性之和。
将书分成只有 Alice 喜欢、只有 Bob 喜欢和他们都喜欢三类。对只有 Alice 喜欢、只有 Bob 喜欢的书分别按 属性排序,顺次合并,并把合并后的书加入到他们都喜欢的书的行列中去。把处理完之后的所有他们都喜欢的书按 属性排序,取前 本求和即可。
代码
#include <bits/stdc++.h>
#define nnn printf("No\n")
#define yyy printf("Yes\n")
using namespace std;
const int N=200001;
int a[4][N],t[4],n,k,ans;
int solve()
{
scanf("%d%d",&n,&k);
for (int i=1,x,y,z;i<=n;++i)
{
scanf("%d%d%d",&x,&y,&z);
a[y*2+z][++t[y*2+z]]=x;
}
sort(a[1]+1,a[1]+1+t[1]);
sort(a[2]+1,a[2]+1+t[2]);
for (int i=1;i<=min(t[2],t[1]);++i) a[3][++t[3]]=a[1][i]+a[2][i];
sort(a[3]+1,a[3]+1+t[3]);
for (int i=1;i<=k;++i) ans+=a[3][i];
printf("%d\n",(t[3]>=k)?ans:-1);
}
int main()
{
int T=1;
solve();
return 0;
}