1101模拟
1101模拟题解
T1
贪心:
将物品按\(a_i\)降序排序,如果有\(a_i\)相同的情况则按升序排序。
显然小A每次会选择排序后未被选取的最靠前的一项。
两个人轮流取,小B在任意前\(i\)件物品中最多能选取\(\lfloor \frac{i+k}{2} \rfloor\)件物品。
在此约束下的目标是求出所取物品对小B价值的最大值。
贪心思路:
每次加入第\(i\)个物品,检查取出数量是否超过限制,如果超过限制,则丢掉已取物品里价值最小的一项,时间复杂度\(O(n~ ~logn)\)
注意开long long
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
return s*w;
}
int T;
int n,k;
struct node{
int a,b;
}e[100010];
int cmp(node x,node y){
if(x.a==y.a) return x.b<y.b;
return x.a>y.a;
}
int cho[100010];
priority_queue<int,vector<int>,greater<int> >q;
int ans;
signed main(){
T=read();
while(T--){
n=read(),k=read();
for(int i=1;i<=n;i++){
e[i].a=read();
}
for(int i=1;i<=n;i++){
e[i].b=read();
}
sort(e+1,e+n+1,cmp);
for(int i=1;i<=n;i++){
q.push(e[i].b);
if((int)q.size()>(i+k)/2) q.pop();
}
ans=0;
while(!q.empty()){
ans+=q.top();
q.pop();
}
printf("%lld\n",ans);
}
return 0;
}