SHU 购买装备 贪心+二分

购买装备(“盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛(重现赛))

发布时间: 2017年7月9日 20:20 时间限制: 1000ms 内存限制: 128M

描述

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

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

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

样例输入1 复制 1
2 4
3 2
2 3

样例输出1 1 3

看起来是两个变量 数量和 属性 ,其实数量固定后就只有一个变量了,就水了
能买到多少个你先球出来就好

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e5+100;
int n,m;
int num;
struct node
{
    int a,v;
}s[maxn];
int sum[maxn];

int cmp(node a,node b)
{
    return a.v<b.v;
}

int check(int x)
{
    int tol=0,cnt=0;;
    for(int i=1;i<=n;i++)
    {
        if(s[i].a>=x)
        {
            cnt++;
            tol+=s[i].v;
        }
        if(cnt>=num)
        {
            break;
        }
    }
    if(tol<=m&&cnt>=num)
    {
        return 1;
    }
    else return 0;

}

int main(){
    int t;
    scanf("%d",&t);
    while(t--)
    {
        num=0;
        int minn=0x3f3f3f3f,maxx=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {

            scanf("%d%d",&s[i].a,&s[i].v);
            minn=min(minn,s[i].a),maxx=max(maxx,s[i].a);
        }
        sort(s+1,s+n+1,cmp);
        int mm=m;
        int ans=0;
        while(ans+s[num+1].v<=mm&&num+1<=n)
        {
            mm-=s[num+1].v;
            num++;
        }
        int l=minn,r=maxx;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(check(mid))
            {
                l=mid+1;
            }
            else r=mid-1;
        }
        printf("%d %d\n",num,r );
    }
}

版权声明:本文为Littlewhite520原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。