E1 - Reading Books (easy version)
题意:一共有n本书,看完每本书都有一个花费时间,每本书上都有两个标记,小a是否喜换,小b是否喜换,小a小b是否共同喜换,他们只会阅读自己喜换的书,他们每个人至少阅读k本书,如果他俩共同喜换,那么花费阅读这一本书的时间,会使他俩已经阅读的书总是各加一,求花费最少时间阅读完成k本书的情况,如果无法完成则输出-1。
题解:
那么我们对每本书的情况进行分类
1.小a喜换小b不喜欢。
2.小b喜换小a不喜欢。
3.小a小b都喜欢。
4.小a小b都不喜欢。
这四种情况,可以看出第4种情况的书没有意义,我们直接丢弃即可(因为没人会去看)
那么我们先特判完不成的情况,如果min(第一种情况,第二种情况)+第三种情况,小于k,那么就说明没有那么多书可以让他们看,直接输出-1;
对于可以完成的情况,我们对a,b数组先排序,(a情况时间+b情况时间)=c情况时间。
所以我们可以把(a情况时间+b情况时间)(每次取最小a和b)丢尽优先队列,然后把c情况丢尽优先队列。
然后取有限队列前k个数相加即可
/*Keep on going Never give up*/ #pragma GCC optimize(3,"Ofast","inline") #include <bits/stdc++.h> const int maxn = 2e5+10; const int MaxN = 0x3f3f3f3f; const int MinN = 0xc0c0c00c; typedef long long ll; const int mod = 100000000; using namespace std; int a[maxn],b[maxn],c[maxn]; int main() { int n,k; cin>>n>>k; int cnt1=0,cnt2=0,cnt3=0; for(int i=0;i<n;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); if(y==1&&z==0) a[cnt1++]=x; else if(y==0&&z==1) b[cnt2++]=x; else if(y==1&&z==1) c[cnt3++]=x; } //cout<<cnt1<<cnt2<<cnt3<<endl; sort(a,a+cnt1); sort(b,b+cnt2); sort(c,c+cnt3); if(cnt3+min(cnt1,cnt2)<k){ cout<<-1<<endl; return 0; } if(cnt3==0){ ll ans=0; for(int i=0;i<k;i++){ ans+=(ll)a[i]+(ll)b[i]; } cout<<ans<<endl; } else{ ll ans=0; priority_queue<ll,vector<ll>,greater<ll> >q; for(int i=0;i<cnt3;i++) q.push((ll)c[i]); for(int i=0;i<min(cnt1,cnt2);i++){ q.push((ll)a[i]+(ll)b[i]); } for(int i=0;i<k;i++){ ans+=q.top(); q.pop(); } cout<<ans<<endl; } return 0; }