Wannafly挑战赛20 B 背包(贪心)

链接:https://www.nowcoder.com/acm/contest/133/B
来源:牛客网

题目描述
Applese有1个容量为v的背包,有n个物品,每一个物品有一个价值ai,以及一个大小bi
然后他对此提出了自己的疑问,如果我不要装的物品装的价值最大,只是一定需要装m个物品,要使得求出来的物品价值的中位数最大
Applese觉得这个题依然太菜,于是他把这个问题丢给了你
当物品数量为偶数时,中位数即中间两个物品的价值的平均值
输入描述:

第一行三个数v, n, m,分别代表背包容量,物品数量以及需要取出的物品数量
接下来n行,每行两个数ai,bi,分别代表物品价值以及大小
n ≤ 1e5, 1 ≤ m ≤ n, ai ≤ 1e9, v ≤ 1e9, bi ≤ v

输出描述:

仅一行,代表最大的中位数

示例1
输入
复制

20 5 3
3 5
5 6
8 7
10 6
15 10

输出
复制

8

按价值排序然后分奇偶讨论就好了
用优先队列维护下就行了

accode

#include<bits/stdc++.h>
#define LL long long
#define INF  0x3f3f3f3f
using namespace std;
const int maxn = 1e5+32;
struct node
{
    LL v,cost;
    bool operator <(const node& p) const{
        if(v==p.v){
            return cost<p.cost;
        }
        return v<p.v;
    }
}Q[maxn];
LL n,m,v;
int dp1[maxn];
int dp2[maxn];
int main()
{
    scanf("%lld%lld%lld",&v,&n,&m);
    for(int i = 1;i<=n;i++){
        scanf("%lld%lld",&Q[i].v,&Q[i].cost);
    }
    sort(Q+1,Q+n+1);
    priority_queue<LL>pq;
    if(m%2){
        //cout<<"ffw"<<endl;
        LL sum = 0;
        int cnt = m/2;
        for(int i = 1;i<=n;i++){
            dp1[i] = sum;
            pq.push(Q[i].cost);
            sum+=Q[i].cost;
            if(pq .size()>cnt){
                LL tmp = pq.top();
                pq.pop();
                sum -= tmp;
            }
        }
        while(pq.size()) pq.pop();
         sum = 0;
        for(int i = n;i>=1;i--){
            dp2[i] = sum;
            pq.push(Q[i].cost);
            if(pq.size()>cnt){
                LL tmp =  pq.top();
                pq.pop();
                sum -= tmp;
            }
            sum+=Q[i].cost;
        }
        for(int i = n-cnt;i>cnt;i--){
            if(dp1[i]+dp2[i]+Q[i].cost<=v){
              //  cout<<dp1[i]<<' '<<dp2[i]<<' '<<i<<endl;
                cout<<Q[i].v<<endl;
                return 0;
            }
        }
    }
    else{
         LL sum = 0;
        int cnt = m/2;
        for(int i = 1;i<=n;i++){
            pq.push(Q[i].cost);
            sum+=Q[i].cost;

            if(pq .size()>cnt){
                LL tmp = pq.top();
                pq.pop();
                sum -= tmp;
            } dp1[i] = sum;
        }
        while(pq.size()) pq.pop();
        sum = 0;
        for(int i = n;i>=1;i--){
            pq.push(Q[i].cost);
            sum+=Q[i].cost;

            if(pq.size()>cnt){
                LL tmp =  pq.top();
                pq.pop();
                sum -= tmp;
            } dp2[i] = sum;
        }
        for(int i = n-cnt;i>=cnt;i--){
            if(dp1[i]+dp2[i+1]<=v){
                cout<<(Q[i].v+Q[i+1].v)/2<<endl;
                return 0;
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/w571523631/article/details/81229083