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;
}
posted @ 2020-11-02 09:28  Luo_Feng_Han  阅读(52)  评论(0编辑  收藏  举报