Codeforces 725D Contest Balloons (贪心+优先队列)

一、题目概述

D. Contest Balloons
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

One tradition of ACM-ICPC contests is that a team gets a balloon for every solved problem. We assume that the submission time doesn't matter and teams are sorted only by the number of balloons they have. It means that one's place is equal to the number of teams with more balloons, increased by 1. For example, if there are seven teams with more balloons, you get the eight place. Ties are allowed.

You should know that it's important to eat before a contest. If the number of balloons of a team is greater than the weight of this team, the team starts to float in the air together with their workstation. They eventually touch the ceiling, what is strictly forbidden by the rules. The team is then disqualified and isn't considered in the standings.

A contest has just finished. There are n teams, numbered 1 through n. The i-th team has ti balloons and weight wi. It's guaranteed that tidoesn't exceed wi so nobody floats initially.

Limak is a member of the first team. He doesn't like cheating and he would never steal balloons from other teams. Instead, he can give his balloons away to other teams, possibly making them float. Limak can give away zero or more balloons of his team. Obviously, he can't give away more balloons than his team initially has.

What is the best place Limak can get?

Input

The first line of the standard input contains one integer n (2 ≤ n ≤ 300 000) — the number of teams.

The i-th of n following lines contains two integers ti and wi (0 ≤ ti ≤ wi ≤ 1018) — respectively the number of balloons and the weight of the i-th team. Limak is a member of the first team.

Output

Print one integer denoting the best place Limak can get.

Examples
input
8
20 1000
32 37
40 1000
45 50
16 16
16 16
14 1000
2 1000
output
3
input
7
4 4
4 4
4 4
4 4
4 4
4 4
5 5
output
2
input
7
14000000003 1000000000000000000
81000000000 88000000000
5000000000 7000000000
15000000000 39000000000
46000000000 51000000000
0 1000000000
0 0
output

二、题目释义

每个队伍有气球数个重量两个参数,排名只按照气球数目从大到小,当一个队伍的气球数大于它的重量时,它就飘起来了(不再计入排名),现在主人公可以给别人任意个气球,问他能获得最高的排名是多少

三、思路分析

贪心的思想,首先气球肯定只会给原先Rank在主人公之前,并且给那些需要气球最少的,所以可以用一个优先队列来存储那些需要被给气球的队伍,但是当主人公给出气球后,可能他原先后面的队伍会超过他,所以要去维护这个队列,当队列为空或主人公气球数目为0时跳出,在每次给出气球的后跟新Rank,取合法的最小值

四、AC代码

#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 3e5+50;
struct team
{
    LL bal,wei,need;
}teams[N];

bool cmp(team a,team b)
{
    return a.bal > b.bal;
}

bool operator < (const team &a, const team &b)
{
    return a.need > b.need;
}

priority_queue<team> Front;

int main()
{
    int n; cin >> n;
    for(int i=0; i<n; i++)
    {
        scanf("%I64d%I64d",&teams[i].bal,&teams[i].wei);
        teams[i].need = teams[i].wei - teams[i].bal + 1;
    }
    team Li = teams[0];
    sort(teams,teams+n,cmp);
    for(int i=0; i<n; i++)
    {
        if(teams[i].bal>Li.bal) Front.push(teams[i]);
        else break;
    }
    int index = Front.size(); // index为主人公队伍在原先数组的下标,之后当后面的队伍往前超的时候需要更新这个index,以确保进入优先队列的数据是合法的
    int Rank = index + 1;
    int maxRank = Rank;
    while(!Front.empty())
    {
        team temp = Front.top();
        Front.pop();
        Li.bal -= temp.need;
        if(Li.bal < 0) break;
        else
        {
            int cnt = 0;
            while(Li.bal<teams[index+1].bal)
            {
                Front.push(teams[index+1]);
                index++;
                cnt++;
            }
            Rank += cnt - 1;
            maxRank = min(maxRank,Rank);
        }
    }
    cout << maxRank << endl;
    return 0;
}