SHoj 420 购买装备

购买装备

发布时间: 2017年7月9日 18:17   最后更新: 2017年7月9日 21:05   时间限制: 1000ms   内存限制: 128M

最近盛大的一款游戏传奇世界极其火爆。游戏玩家John,想购买游戏中的装备。已知游戏的商店里有 件装备,第 件装备具有属性值i   ,购买需要花费i   个金币。John想去购买这些装备,但是账号中只有 个金币,John是个很贪婪的家伙,他想购买尽可能多的装备。并且在保证购买到最多件装备的情况下,他还想让他所购买的装备当中拥有最小属性值的装备属性值尽可能大

输入测试组数 ,每组数据第一行输入整数 (1<=n<=100000  )和 (1<=m<=10 9   ), 接下来有 行,第 行有两个数i   , i   (1<=i   ,<=10000  ).

对于每组数据,输出两个数字,第一个数字代表John最多可以购买的装备数,第二个数代表在John购买最多件装备的前提下,所购买的装备当中拥有最小属性值的装备的最大属性值(输入数据保证至少可以购买一件装备)

复制
1
2 4
3 2
2 3
1 3

思路:贪心+二分,首先按照价格从小到大对装备进行排序,贪心选取尽量多的装备数x,在这个装备数量x的前提下对所有选取的装备最小属性值y进行二分搜索,若装备属性值大于等于当前最小属性值的并且能够购买的最多的装备的数量小于x,则最小属性值偏大,可以再小点,否则再调整大一点,二分。。
AC代码:
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<algorithm>
#include<queue>
#include<set>
#include<vector>
#include<cstring>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
const int N_MAX = 100000+4;
int t,n;//n件装备,m个金币
ll m;
int num = 0;//num为购买装备数
int SXZ[N_MAX];
struct zhuangbei {
int a, b;//ai属性值,bi金币
zhuangbei() {}
zhuangbei(int a,int b):a(a),b(b){
}
bool operator <(const zhuangbei &B)const {
    if (this->b != B.b) return this->b < B.b;
    else return this->a > B.a;
}
}zb[N_MAX];

bool C(int shuxing) {
    ll sum =0;
    int res=0;//买的装备数
    for (int i = 0; i < n;i++) {
        if (sum+zb[i].b<=m) {//装备价格能接受
            if (zb[i].a>=shuxing) {//且当前装备属性值大于等于最低属性值,买
                sum += zb[i].b;
                res++;
                if (res >= num)break;//能买的装备足够多了
            }
        }
        else break;
    }
    if (res<num)return false;//能挑选的数量太少,说明属性值还应该低一些
    else return true;
}


int main() {
    scanf("%d",&t);
    while (t--) {
        num = 0;
        scanf("%d%lld",&n,&m);
        for (int i = 0; i < n;i++) {
            scanf("%d%d",&zb[i].a,&zb[i].b);
            SXZ[i] = zb[i].a;
        }
        sort(zb, zb + n);
        sort(SXZ,SXZ+n);//对属性值从小到大排,二分出来的属性值必须是其中之一
        ll add = 0;
        for (int i = 0; i < n;i++) {
            add += zb[i].b;
            if (add <= m)num++;
        }
        int lb = 0, ub = n;
        while (ub-lb>1) {
            int mid = (ub+lb)>>1;
            if (C(SXZ[mid]))lb = mid;
            else ub = mid;
        }
        printf("%d %d
",num,SXZ[lb]);

    }
        return 0;
}
原文地址:https://www.cnblogs.com/ZefengYao/p/7208503.html