Problem:
 Score : 400 points    Problem Statement You are going out for a walk, when you suddenly encounter a monster. Fortunately, you have N katana (swords), Katana 1 , Katana 2 , … , Katana N , and can perform the following two kinds of attacks in any order:   Wield one of the katana you have. When you wield Katana i  (1 ≤ i ≤ N) , the monster receives a_i points of damage. The same katana can be wielded any number of times.  Throw one of the katana you have. When you throw Katana i  (1 ≤ i ≤ N) at the monster, it receives b_i points of damage, and you lose the katana. That is, you can no longer wield or throw that katana.   The monster will vanish when the total damage it has received is H points or more. At least how many attacks do you need in order to vanish it in total?      Constraints  1 ≤ N ≤ 10^5  1 ≤ H ≤ 10^9  1 ≤ a_i ≤ b_i ≤ 10^9  All input values are integers.         Input Input is given from Standard Input in the following format:  N  H  a_1  b_1  :  a_N  b_N       Output Print the minimum total number of attacks required to vanish the monster.        Sample Input 1 1 10
3 5      Sample Output 1 3  You have one katana. Wielding it deals 3 points of damage, and throwing it deals 5 points of damage. By wielding it twice and then throwing it, you will deal 3 + 3 + 5 = 11 points of damage in a total of three attacks, vanishing the monster.       Sample Input 2 2 10
3 5
2 6      Sample Output 2 2  In addition to the katana above, you also have another katana. Wielding it deals 2 points of damage, and throwing it deals 6 points of damage. By throwing both katana, you will deal 5 + 6 = 11 points of damage in two attacks, vanishing the monster.       Sample Input 3 4 1000000000
1 1
1 10000000
1 30000000
1 99999999      Sample Output 3 860000004       Sample Input 4 5 500
35 44
28 83
46 62
31 79
40 43      Sample Output 4 9

Solution (Python):
n,h = map(int,input().split())
slash = []
throw = []
for i in range(n):
    s,t = map(int,input().split())
    slash.append(s)
    throw.append(t)
    
Amax = sorted(slash)[-1]
throw = sorted(throw)
use = [Amax]
for i in range(n):
    if throw[i] > Amax:
        use = [Amax] + throw[i:]
        break

damage = 0
count = 0
while h > damage:
    if use != []:
        damage += use.pop(-1)
        count += 1
    else:
        count += (h-damage)//Amax + ((h-damage)%Amax != 0)
        break
    
print(count)

Solution (Python):
n, h = map(int, input().split())

ab = [list(map(int, input().split())) for _ in range(n)]
a_max = sorted(ab, key=lambda x: x[0], reverse=True)[0][0]
ab_sorted = sorted(ab, key=lambda x: x[1], reverse=True)

ans = 0

for i in range(n):
    if a_max > ab_sorted[i][1]:
        break
    h = h - ab_sorted[i][1]
    ans += 1
    if h <= 0:
        print(ans)
        exit(0)


add = h//a_max if h % a_max == 0 else h//a_max + 1
print(ans + add)

Solution (Python):
n, h = map(int, input().split())
A = []
B = []
for _ in range(n):
    a, b = map(int, input().split())
    A.append(a)        
    B.append(b)        

maxa = max(A)
B = [b for b in B if b > maxa]
B.sort(reverse=True)

c = 0
for b in B:
    h -= b
    c += 1
    if h <= 0:
        break

if h > 0:
    c += h//maxa + (h%maxa > 0)
print(c)

Solution (Python):
n,h = map(int,input().split())
a_list = []
b_list = []
use_b_list = []
for i in range(n):
  a,b = map(int,input().split())
  a_list.append(a)
  b_list.append(b)
use_a = max(a_list)
import math
for b in b_list:
  if b > use_a:
    use_b_list.append(b)
use_b_list.sort(reverse = True)    
count = 0
if sum(use_b_list) >= h:
  for i in range(len(use_b_list)):
    h -= use_b_list[i]
    count += 1
    if h <= 0:
      break
  print(count)
else:
  h -= sum(use_b_list)
  print(len(use_b_list) + int(math.ceil(h/max(a_list))))

Solution (Python):
import math
def resolve():
    N, H = list(map(int, input().split()))
    attacks = []
    for i in range(N):
        a, b = list(map(int, input().split()))
        attacks.append((a, 0))
        attacks.append((b, 1))
    attacks = sorted(attacks)
    damage = 0
    cnt = 0
    while damage < H:
        dam, once = attacks.pop()
        damage += dam
        cnt += 1
        if not once:
            cnt += math.ceil((H - damage) / dam)
            break
    print(cnt)



if '__main__' == __name__:
    resolve()

Solution (Python):

import copy
import random
import bisect 
import fractions 
import math
import sys
import collections

mod = 10**9+7
sys.setrecursionlimit(mod) 

d = collections.deque()
def LI(): return list(map(int, sys.stdin.readline().split()))

N, H = LI()
ab = [[]] * N
a = [0] * N
b = [0] * N

for i in range(N):
    a[i], b[i] = LI()
    ab[i] = [a[i], b[i]]

a_max = max(a)
ans = 0
b.sort(reverse= 1)
for i in range(N):
    if H <= 0:
        break
    if b[i] > a_max:
        H -= b[i]
        ans += 1
if H > 0:
    ans += math.ceil(H / a_max)
print(ans)

Solution (Python):
n,h=map(int,input().split())
a=list()
b=list()
for i in range(n):
    j,k=map(int,input().split())
    a.append(j)
    b.append(k)

maxa=max(a)
if maxa>max(b):
    print(-h//maxa*-1)
else:
    b.sort(reverse=True)
    p=0
    for i in range(n):
        p+=b[i]
        if p>=h:
            print(i+1)
            break
        if b[i]<maxa:
            print(i+((p-h-b[i])//maxa)*-1)
            
            break
    else:
        print(n+((p-h)//maxa)*-1)

Solution (Python):
import math
def main():
    n, h = list(map(int, input().split()))
    A, B = [], []
    for _ in range(n):
        a, b = list(map(int, input().split()))
        A.append(a)
        B.append(b)
    a_max = max(A)
    B = list(filter(lambda x: x > a_max, B))
    B.sort(reverse = True)
    ans = 0
    for b in B:
        h -= b
        ans += 1
        if h <= 0:
            break
    else:
        ans += math.ceil(h / a_max)
    print(ans)

if __name__ == '__main__':
    main()

Solution (Python):
n,h = map(int,input().split())
a = []
b = []
for i in range(n):
    ai,bi = map(int,input().split())
    a.append(ai)
    b.append(bi)
a.sort(reverse=True)
b.sort(reverse=True)
ans = 0
damage = 0
for i in b:
    if i > a[0]:
        damage += i
        ans += 1
        if damage >= h:
            print(ans)
            exit()
h -= damage
print(ans + (h+a[0]-1)//a[0])

Solution (Python):
from collections import deque
N, H = map(int, input().split())
a, b = [], []
for _ in range(N):
    a_, b_ = map(int, input().split())
    a.append(a_)
    b.append(b_)
a.sort()
b.sort()
maxa = a[-1]
que = deque(b)
cnt = 0
while H > 0:
    if not que:
        cnt += -(-H//maxa)
        break
    maxb = que.pop()
    if maxb > maxa:
        cnt += 1
        H -= maxb
    else:
        cnt += -(-H//maxa)
        break
print(cnt)

Solution (Python):
n, h = map(int,input().split())
a = []
b = []
ans = 0

for i in range(n):
    x, y = map(int,input().split())
    a.append(x)
    b.append(y)

b.sort(reverse=True)
c = max(a)


for i in b:
    if i > c:
        h -= i
        ans += 1
        if h <= 0:
            print(ans)
            exit()


ans += (h+c-1)//c
print(ans)

Solution (Python):


















import sys
sys.setrecursionlimit(10000000)
mod = 10**9 + 7

def readInts():
  return list(map(int,input().split()))
def I():
  return int(input())
n,h = readInts()
a = [0] * n
b = [0] * n
for i in range(n):
    a_,b_ = readInts()
    a[i] = a_;b[i]=b_;
a = sorted(a,reverse = True)
b = sorted(b,reverse = True)
MAX = a[0]
ans = 0
for v in b:
    if h <= 0:
        break
    if v > MAX:
        ans += 1
        h -= v
    else:
        break
if h > 0:
    ans += (h+MAX-1)//MAX
print(ans)

Solution (Python):
n,h= map(int, input().split())
a = 0
num = 0
b = []
for i in range(n):
  c,d = map(int, input().split())
  if c > a:
    a = c
    num = i
  b.append(d)
cnt = 0
b2 = b[num]
b = sorted(b)
if a >= max(b):
  if h%a == 0:
    print(h//a)
  else:
    print(h//a + 1)
  exit(0)
  
for i,j in enumerate(b):
  if j > a:
    b = sorted(b[i:], reverse=True)
    break
for i in b:
  h -= i
  cnt += 1
  if h <= 0:
    print(cnt)
    exit(0)
if h%a == 0:
  print(cnt + h//a)
else:
  print(cnt + h//a + 1)

Solution (Python):
import sys
import copy
from collections import deque
stdin = sys.stdin

ni = lambda: int(ns())
na = lambda: list(map(int, stdin.readline().split()))
ns = lambda: stdin.readline().rstrip()  

n, h = na()
ab = [na() for i in range(n)]

attack = []
for p in ab:
    attack.append([p[0], 0])
    attack.append([p[1], 1])

attack.sort(reverse=True)

cnt = 0
for a in attack:
    if a[1]==1:
        cnt += 1
        h -= a[0]
    else:
        cnt += h//a[0] if h%a[0]==0 else h//a[0] + 1
        h = 0
    if h <= 0:
        break

print(cnt)

Solution (Python):
import bisect
from math import ceil

N,H,*abf = map(int, open(0).read().split())
ab = [abf[i:i+2] for i in range(0, len(abf), 2)]
a = sorted([x[0] for x in ab],reverse=True)
b = sorted([x[1] for x in ab],reverse=True)
br = list(reversed(b))
bs = bisect.bisect_right(br,a[0])
ans = 0
rem = H
for i in range(N-bs):
    rem -= b[i] 
    ans += 1
    if rem <= 0:
        print(ans)
        break
else:
    ans += ceil(rem/a[0])
    print(ans)

Solution (Python):
import bisect
import math

n, h = map(int, input().split())
A, B = [], []
for i in range(n):
    a, b = map(int, input().split())
    A.append(a)
    B.append(b)
atk = max(A)
B.sort(reverse=True)
L = [0]
for i in range(n):
    if B[i] >= atk:
        L.append(L[-1] + B[i])
    else:
        break
if L[-1] >= h:
        ans = bisect.bisect_left(L, h)
else:
    h -= L[-1]
    ans = len(L) - 1 + math.ceil(h / atk)
print(ans)

Solution (Python):
def main():
    n,h = list(map(int, input().split()))
    bi = []
    max_attack = [0,0]
    for i in range(n):
        a, b = list(map(int, input().split()))
        bi.append(b)
        max_attack[0] = max(a, max_attack[0])
        max_attack[1] = max(b, max_attack[1])
    bi.sort(reverse=True)
    idx = 0
    count = 0
    while h > 0:
        damage = 0
        if idx < len(bi) and max_attack[0] < bi[idx]:
            damage = bi[idx]
            idx += 1
        else:
            count += h // max_attack[0]
            count += 0 if h % max_attack[0] == 0 else 1
            break
        h -= damage
        count += 1
    print(count)



if __name__ == '__main__':
    main()

Solution (Python):
N, H = map(int, input().split())

a = [0] * N
b = [0] * N

ab = []
for i in range(N):
  ai, bi = map(int, input().split())
  a[i] = -ai
  b[i] = -bi
  ab.append((-ai, -bi))
  
ab.sort()
b.sort()
mina = ab[0][0]

ans = 0
for bi in b:
  if bi <= mina:
    H += bi
    ans += 1
    if H <= 0:
      print(ans)
      exit()
  else:
    ans += (H-1)//(-mina) + 1
    print(ans)
    exit()
ans += (H-1)//(-mina) + 1
print(ans)

Solution (Python):
import numpy as np
import math
N, H = map(int, input().split())
a_list = []
b_list = []
for _ in range(N):
    a, b = map(int, input().split())
    a_list.append(a)
    b_list.append(b)

a_max = max(a_list)
b_list.sort()
def judge(H, n, a_max, b_list):
    b_copy = b_list.copy()
    count = 0
    while H > 0:
        if len(b_copy) == 0:
            count += math.ceil(H / a_max)
            break
        else:
            b_max = b_copy.pop()
            if a_max > b_max:
                count += math.ceil(H / a_max)
                break
            else:
                H -= b_max
                count += 1
    if count <= n:
        return True
    return False

right = 10 ** 9
left = 1
while right != left:
    
    mid = (left + right) // 2
    if judge(H, mid, a_max, b_list):
        right = mid
    else:
        left = mid + 1

print(left)

Solution (Python):
import bisect
import sys

N, H = map(int, input().split())
ab = [map(int, input().split()) for _ in range(N)]
a, b = [list(i) for i in zip(*ab)]

a_max = max(a)
b.sort(reverse=True)

l = [b[i] for i in range(N) if b[i] >= a_max]
d = 0
cnt = 0
for v in l:
    d += v
    cnt += 1
    if d >= H:
        print(cnt)
        sys.exit()
cnt += (H-d+a_max-1)//a_max
print(cnt)

Solution (Python):
def main():
    from math import ceil
    n, h, *ab = map(int, open(0).read().split())

    *c, = map(lambda x: -x, ab[::2])
    d = sorted(c + ab[1::2], key=abs, reverse=True)
    ans = 0
    for x in d:
        if x < 0:
            ans += ceil(h / abs(x))
            break

        h -= x
        ans += 1
        if h <= 0:
            break

    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
def main():
    from math import ceil
    from itertools import accumulate
    from bisect import bisect_left
    n, h, *ab = map(int, open(0).read().split())

    x = max(ab[::2])
    *y, = filter(lambda i: i >= x, ab[1::2])
    y = sorted(y, reverse=True)
    *z, = accumulate(y)

    if z[-1] <= h:
        print(len(y) + ceil((h - z[-1]) / x))
    else:
        print(bisect_left(z, h) + 1)


if __name__ == '__main__':
    main()

Solution (Python):
def main():
    from math import ceil
    from itertools import accumulate
    from bisect import bisect_left
    n, h, *ab = map(int, open(0).read().split())

    x = max(ab[::2])
    *y, = filter(lambda i: i >= x, ab[1::2])
    y.sort(reverse=True)
    *z, = accumulate(y)

    if z[-1] <= h:
        print(len(y) + ceil((h - z[-1]) / x))
    else:
        print(bisect_left(z, h) + 1)


if __name__ == '__main__':
    main()

Solution (Python):
def main():
    from collections import deque
    from math import ceil
    n, h, *ab = map(int, open(0).read().split())
    a = ab[::2]
    *b, = map(lambda x: -x, ab[1::2])
    c = a + b
    c.sort(key=lambda x: abs(x), reverse=True)

    q = deque(c)
    cnt = 0
    while h > 0:
        cnt += 1
        x = q.popleft()
        h -= abs(x)
        if x > 0:
            cnt += ceil(h / x)
            break

    print(cnt)


if __name__ == '__main__':
    main()

Solution (Python):
import sys

def LI(): return list(map(int,sys.stdin.readline().rstrip().split()))  
def S(): return sys.stdin.readline().rstrip()

N,H = map(int,S().split())
ab = [LI() for i in range(N)]

A = [(ab[i][0],1) for i in range(N)]
B = [(ab[i][1],2) for i in range(N)]

from operator import itemgetter

C = sorted(A+B,key = itemgetter(0),reverse=True)

damage = 0  
ans = 0  
for i in range(2*N):
    if C[i][1] == 1:
        ans += (H-damage+C[i][0]-1)//C[i][0]
        break
    else:
        ans += 1
        damage += C[i][0]
        if damage >= H:
            break

print(ans)

Solution (Python):
import numpy as np
import math

N, H = 2, 10
ARR = [
    [3, 5],
    [2, 6]
]

N, H = 4, 1000000000
ARR = [
    [1, 1],
    [1, 10000000],
    [1, 30000000],
    [1, 99999999]
]

N, H = 5, 500
ARR = [
    [35, 44],
    [28, 83],
    [46, 62],
    [31, 79],
    [40, 43]
]

N, H = map(int, input().split())
ARR = [list(map(int,input().split())) for i in range(N)]


def calculate(n, h, arr):
    arr = np.array(arr)
    A1 = arr[:, 0]
    B1 = arr[:, 1]

    largestA1 = max(A1)

    b2 = sorted(B1, key=lambda x: -x)

    result = 0
    for i in range(len(b2)):

        if h <= 0:
            break
        if b2[i] >= largestA1:
            h = h - b2[i]
            result += 1
        else:
            break

    if h > 0:
        result += math.ceil(h / largestA1)

    return result


res = calculate(N, H, ARR)
print(res)

Solution (Python):
import sys
import math

n, h = map(int, input().split())
a = 0
b = []

for i in range(n):
    x, y = map(int, input().split())
    a = max(a, x)
    b.append(y)

b.sort(reverse=True)

b = [x for x in b if x > a]

for i, x in enumerate(b):
    h -= x
    if h <= 0:
        print(i + 1)
        sys.exit()

if len(b) == 0:
    i = -1

ans = i + 1 + math.ceil(h / a)

print(ans)

Solution (Python):
n, h = map(int, input().split())
AB = [list(map(int, input().split())) for i in range(n)]
A,B = zip(*AB)
a = max(A)
B = [b for b in B if b > a]
B.sort(reverse=True)
ans = 0
hp = h
attack_cnt = 0
for b in B:
    if hp <= 0:
        break
    attack_cnt += 1
    hp -= b
if hp > 0:
    attack_cnt += (hp - 1) // a + 1
print(attack_cnt)

Solution (Python):
import sys

input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)


def main():
    N, H = map(int, input().split())
    A = []
    B = []
    for i in range(N):
        a, b = map(int, input().split())
        A.append(a)
        B.append(b)

    A.sort()
    B.sort(reverse=True)

    throw = []
    for i in range(N):
        if B[i] > A[-1]:
            throw.append(B[i])
    
    throw = throw[::-1]

    ans = 0

    while H > 0:
        if throw:
            H -= throw.pop()
            ans += 1
        else:
            need_try = (H + A[-1] - 1) // A[-1]
            ans += need_try
            break

    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):
import sys
import numpy as np
from bisect import bisect_left

input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)


def main():
    N, H = map(int, input().split())
    A = []
    B = []
    for i in range(N):
        a, b = map(int, input().split())
        A.append(a)
        B.append(b)

    A.sort()
    B.sort(reverse=True)

    throw = []
    for i in range(N):
        if B[i] > A[-1]:
            throw.append(B[i])
    
    throw = throw[::-1]

    ans = 0

    while H > 0:
        if throw:
            H -= throw.pop()
            ans += 1
        else:
            need_try = (H + A[-1] - 1) // A[-1]
            ans += need_try
            break

    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):
N, H = map(int, input().split())

A = []
B = []
a_max = 0
for _ in range(N):
    a, b = map(int, input().split())
    a_max = max(a, a_max)
    A.append(a)
    B.append(b)

B = sorted(B, reverse=True)

ans = 0
f = 0

for i in B:
    if i < a_max:
        continue
    ans += 1
    H -= i
    if H <= 0:
        f = 1
        break

if f:
    print(ans)
else:
    if H%a_max == 0:
        print(ans + H//a_max)
    else:
        print(ans + H//a_max+1)

Solution (Python):
n,h = map(int,input().split())
katana_a = []
katana_b = []
for i in range(n):
    a,b = map(int,input().split())
    katana_a.append(a)
    katana_b.append(b)
amax = max(katana_a)
katana_b.sort(reverse=True)
ans = 0
k = 0
while h > 0:
    if k == n:
        break
    if katana_b[k] > amax:
        h -= katana_b[k]
        ans += 1
        k += 1
    else:
        break
if h <= 0:
    print(ans)
else:
    print(ans + (h+amax-1)//amax)

Solution (Python):
from math import ceil
n,h = map(int,input().split())
a,b = [],[]
for _ in range(n):
    a_,b_ = map(int,input().split())
    a.append(a_)
    b.append(b_)
mx_a = max(a)
b.sort(reverse=True)
cnt = 0
tmp = 0
for b_ in b:
    if b_ >= mx_a:
        tmp += b_
        cnt += 1
        if tmp >= h:
            print(cnt)
            exit()
    else:
        break
print(cnt+ceil((h-tmp)/mx_a))

Solution (Python):
import math as m1
n, h = map(int, input().split())
a, b = [], []
for i in range(n):
    a_, b_ = map(int, input().split())
    a.append(a_)
    b.append(b_)
b = list(reversed(sorted(b)))
m = max(a)
ans = 0
for i in b:
    if i > m:
        if h - i <= 0:
            print(ans + 1)
            exit()
        h -= i
        ans += 1
print(ans + m1.ceil(h / m))

Solution (Python):
n,h=map(int,input().split())
p=[]
for i in range(n):
    a,b=map(int,input().split())
    p.append([a,0])
    p.append([b,1])

p=sorted(p,key=lambda x:-x[0])

i=0
ans=0
while h>0:
    if p[i][1]==1:
        h-=p[i][0]
        ans+=1
        i+=1
    else:
        ans-=(-h//p[i][0])
        break

print(ans)

Solution (Python):
n, h = map(int, input().split())
ab = []
for i in range(n):
    a, b = map(int, input().split())
    ab.append((a, "a"))
    ab.append((b, "b"))

ab.sort(reverse=True, key=lambda x: x[0])

count = 0
for x, y in ab:
    if h <= 0:
        break
    if y == "a":
        if h%x == 0:
            count += h//x
            h = 0
        else:
            count += h//x + 1
            h = 0
    if y == "b":
        h -= x
        count += 1

print(count)

Solution (Python):
import sys
import math
from collections import defaultdict
from bisect import bisect_left, bisect_right

sys.setrecursionlimit(10**7)
def input():
    return sys.stdin.readline()[:-1]

mod = 10**9 + 7

def I(): return int(input())
def LI(): return list(map(int, input().split()))
def LIR(row,col):
    if row <= 0:
        return [[] for _ in range(col)]
    elif col == 1:
        return [I() for _ in range(row)]
    else:
        read_all = [LI() for _ in range(row)]
        return map(list, zip(*read_all))



def ceil(a,b):
    return a//b + int(a%b != 0)

N,H = LI()
a,b = LIR(N,2)

x = []
for i in range(N):
    x.append((a[i],0))
    x.append((b[i],1))

x.sort(key=lambda x: (-x[0],x[1]))

val = 0
count = 0
for x0 in x:
    if x0[1] == 0:
        use_a = x0[0]
        break
    else:
        val += x0[0]
        count += 1
        if val >= H:
            print(count)
            exit()

H -= val
ans = count + ceil(H,use_a)
print(ans)

Solution (Python):
import sys
readline = sys.stdin.readline

N,H = map(int,readline().split())
maxA = 0
B = [0] * N
for i in range(N):
  a,b = map(int,readline().split())
  B[i] = b
  if maxA < a:
    maxA = a

usefulB = []
for i in range(N):
  if B[i] > maxA:
    usefulB += [B[i]]

usefulB = sorted(usefulB,reverse = True)

cnt = 0
for b in usefulB:
  H -= b
  cnt += 1
  if H <= 0:
    print(cnt)
    break
else:
  cnt += (H + maxA - 1) // maxA
  print(cnt)

Solution (Python):
n,h=map(int,input().split())
p=[]
for i in range(n):
    a,b=map(int,input().split())
    p.append([a,0])
    p.append([b,1])

p=sorted(p,key=lambda x:-x[0])

i=0
ans=0
while h>0:
    if p[i][1]==1:
        h-=p[i][0]
        ans+=1
        i+=1
    else:
        ans-=(-h//p[i][0])
        break

print(ans)

Solution (Python):
import sys


import math
import collections

import bisect
import itertools
import fractions

import copy
import heapq
import decimal

import queue

sys.setrecursionlimit(10000001)
INF = 10 ** 16
MOD = 10 ** 9 + 7

ni = lambda: int(sys.stdin.readline())
ns = lambda: map(int, sys.stdin.readline().split())
na = lambda: list(map(int, sys.stdin.readline().split()))





def main():
    n, h = ns()
    a = []
    b = []
    for i in range(n):
        ai, bi = ns()
        a.append((ai, i))
        b.append((bi, i))

    a = sorted(a, key=lambda x: x[0], reverse=True)
    b = sorted(b, key=lambda x: x[0], reverse=True)

    a_max = a[0][0]
    a_max_idx = a[0][1]

    sum_b = 0
    b_cnt = 0
    for i in range(n):
        if b[i][0] > a_max:
            b_cnt += 1
            sum_b += b[i][0]

    cnt = 0
    if sum_b <= h:
        cnt += (h - sum_b + a_max - 1) // a_max
        cnt += b_cnt
    else:
        for i in range(n):
            h -= b[i][0]
            cnt += 1
            if h <= 0:
                break

    print(cnt)


if __name__ == '__main__':
    main()

Solution (Python):






import sys
input = sys.stdin.readline

import math

import bisect
from collections import defaultdict
from collections import deque
from functools import lru_cache






MOD = 10**9+7
INF = float('inf')






def I(): return int(input().strip())
def S(): return input().strip()
def IL(): return list(map(int,input().split()))
def SL(): return list(map(str,input().split()))
def ILs(n): return list(int(input()) for _ in range(n))
def SLs(n): return list(input().strip() for _ in range(n))
def ILL(n): return [list(map(int, input().split())) for _ in range(n)]
def SLL(n): return [list(map(str, input().split())) for _ in range(n)]


def P(arg): print(arg); return
def Y(): print("Yes"); return
def N(): print("No"); return
def E(): exit()
def PE(arg): print(arg); exit()
def YE(): print("Yes"); exit()
def NE(): print("No"); exit()


def DD(arg): return defaultdict(arg)



def inv(n): return pow(n, MOD-2, MOD)


kaijo_memo = []
def kaijo(n):
  if(len(kaijo_memo) > n):
    return kaijo_memo[n]
  if(len(kaijo_memo) == 0):
    kaijo_memo.append(1)
  while(len(kaijo_memo) <= n):
    kaijo_memo.append(kaijo_memo[-1] * len(kaijo_memo) % MOD)
  return kaijo_memo[n]

gyaku_kaijo_memo = []
def gyaku_kaijo(n):
  if(len(gyaku_kaijo_memo) > n):
    return gyaku_kaijo_memo[n]
  if(len(gyaku_kaijo_memo) == 0):
    gyaku_kaijo_memo.append(1)
  while(len(gyaku_kaijo_memo) <= n):
    gyaku_kaijo_memo.append(gyaku_kaijo_memo[-1] * pow(len(gyaku_kaijo_memo),MOD-2,MOD) % MOD)
  return gyaku_kaijo_memo[n]

def nCr(n,r):
  if(n == r):
    return 1
  if(n < r or r < 0):
    return 0
  ret = 1
  ret = ret * kaijo(n) % MOD
  ret = ret * gyaku_kaijo(r) % MOD
  ret = ret * gyaku_kaijo(n-r) % MOD
  return ret


def factorization(n):
  arr = []
  temp = n
  for i in range(2, int(-(-n**0.5//1))+1):
    if temp%i==0:
      cnt=0
      while temp%i==0: 
        cnt+=1 
        temp //= i
      arr.append([i, cnt])
  if temp!=1:
    arr.append([temp, 1])
  if arr==[]:
    arr.append([n, 1])
  return arr


def make_divisors(n):
  divisors = []
  for i in range(1, int(n**0.5)+1):
    if n % i == 0:
      divisors.append(i)
      if i != n // i: 
        divisors.append(n//i)
  return divisors


def gcd(a, b):
    while b:
        a, b = b, a % b
    return a


def lcm(a, b):
    return a * b // gcd (a, b)


def count_bit(n):
  count = 0
  while n:
    n &= n -1
    count += 1
  return count


def base_10_to_n(X, n):
  if X//n:
    return base_10_to_n(X//n, n)+[X%n]
  return [X%n]

def base_n_to_10(X, n):
  return sum(int(str(X)[-i-1])*n**i for i in range(len(str(X))))


def int_log(n, a):
  count = 0
  while n>=a:
    n //= a
    count += 1
  return count





N,H = IL()
S = ILL(N)

MAX = max(a for a,b in S)
B = [b for a,b in S]

B.sort()

ans = 0
while B and H>0:
  h = B.pop()
  if h>MAX:
    H -= h
    ans += 1
  else:
    break
    
print(ans + max(-(-H//MAX),0))

Solution (Python):
n,h,*d=map(int,open(0).read().split())
a=max(d[::2])
b=sorted(d[1::2])
c=0
while b and b[-1]>a>0<h:h-=b.pop();c+=1
print(c--h*(h>0)//a)

Solution (Python):
n,h = map(int,input().split())
A = []
B = []
ans = 0
for i in range(n):
    a,b = map(int,input().split())
    A.append(a)
    B.append(b)


maxa = max(A)


minb = 10**10
s = 0
for i in range(n):
    if A[i] == maxa and B[i] < minb:
        minb = B[i]
        s = i
B.pop(s)


B.sort(reverse = True)
for i in range(len(B)):
    if B[i] > maxa:
        h = h - B[i]
        ans += 1
        if h <= 0:
            print(ans)
            exit()
    else:
        break


h = h - minb
ans += 1
if h <= 0:
    print(ans)
else:
    ans += (h+(maxa-1)) // maxa
    print(ans)

Solution (Python):
n,h,*d=map(int,open(0).read().split());a=max(d[::2]);b=sorted(d[1::2]);c=0
while b and b[-1]>a>0<h:h-=b.pop();c+=1
print(c--h*(h>0)//a)

Solution (Python):
n,h,*d=map(int,open(0).read().split());a=max(d[::2]);b=sorted(d[1::2]);c=0
while b and b[-1]>a>0<h:h-=b.pop();c+=1
print(c-(-h//a)*(h>0))

Solution (Python):
n,h,*d=map(int,open(0).read().split());a=max(d[::2]);b=sorted(d[1::2]);c=0
while b and(h>0)*(b[-1]>a):h-=b.pop();c+=1
while b and b[-1]>a>0<h:h-=b.pop();c+=1
print(c-(-h//a)*(h>0))

Solution (Python):
n,h,*d=map(int,open(0).read().split());a=max(d[::2]);b=sorted(d[1::2]);c=0
while b and(h>0)*(b[-1]>a):h-=b.pop();c+=1
print(c-(-h//a)*(h>0))

Solution (Python):
n,h,*d=map(int,open(0).read().split());a=max(d[::2]);b=sorted(d[1::2]);c=0
while b and(h>0)*(b[-1]>a):h-=b.pop();c+=1
c-=(-h//a)*(h>0)
print(c)

Solution (Python):

n, h, *d = map(int, open(0).read().split())
a = max(d[::2])
b = sorted(b for b in d[1::2] if b >= a)[::-1]
i = 0
for b in b:
    h -= b
    i += 1
    if h <= 0:
        print(i)
        exit()
print(i + 0--h // a)

Solution (Python):
from sys import stdin
def main():
    
    readline=stdin.readline
    n,h=map(int,readline().split())
    li=[list(map(int,readline().split())) for _ in range(n)]
    li.sort(key=lambda x:x[1])
    a_max=0
    j=-1
    for i in range(n):
        if a_max<li[i][0]:
            a_max=li[i][0]
            j=i
    flags=[True]*n
    is_killed=False
    cnt=0
    for i in range(n-1,-1,-1):
        if i==j:
            if h<=li[i][1]:
                cnt+=1
                is_killed=True
                break
        elif a_max<li[i][1]:
            cnt+=1
            flags[i]=False
            h-=li[i][1]
            if h<=0:
                is_killed=True
                break
        else:
            break

    if is_killed:
        print(cnt)
    else:
        if h<=li[j][1]:
            cnt+=1
        elif li[j][0]>=li[j][1]:
            cnt+=(h+a_max-1)//a_max
        else:
            cnt+=1
            h-=li[j][1]
            cnt+=(h+a_max-1)//a_max
    
        print(cnt)

if __name__=="__main__":
    main()

Solution (Python):
import sys
import math

input = sys.stdin.readline

def main():
    N, H = map(int, input().split())
    katana = []
    for _ in range(N):
        a, b = map(int, input().split())
        katana.append([a, 1])
        katana.append([b, 0])
    
    katana.sort(key=lambda x: x[0])
    nage = 0; ans = 0
    while True:
        tmp = katana.pop()
        nage += tmp[0]*(tmp[1] == 0)
        ans += (tmp[1] == 0)
        if nage >= H:
            print(ans)
            return
        if tmp[1] == 1:
            attack = tmp[0]
            break

    ans += math.ceil((H - nage)/attack)
    print(ans)

if __name__ == "__main__":
    main()

Solution (Python):

import bisect
import math

n, h = map(int, input().split())
a, b = [0] * n, [0] * n
for i in range(n):
    a[i], b[i] = map(int, input().split())
max_a = max(a)
b.sort()
idx = bisect.bisect_right(b, max_a)
ans = 0
tmp = 0
for i in range(n - 1, -1, -1):
    tmp += b[i]
    if tmp >= h:
        print(n - i)
        exit()
    if i <= idx:
        break

print(n - idx + math.ceil((h - sum(b[idx:])) / max_a))

Solution (Python):
from math import ceil

def attack(ab,N,H):
    cut_max = 0
    for i in range(N):
        cut_max = max(cut_max,ab[i][0])

    throw = [ab[i][1] for i in range(N)]
    throw.sort(reverse = True)
    throw.append(0)

    cnt,pt = 0,0
    while H > 0:
        if throw[pt] > cut_max:
            H -= throw[pt]
            cnt += 1
            pt += 1
        else:
            cnt += (ceil(H/cut_max))
            H = 0

    return cnt

def main():
    N,H = map(int,input().split())
    ab = [list(map(int,input().split())) for _ in range(N)]

    print(attack(ab,N,H))

if __name__ == "__main__":
    main()

Solution (Python):
n,h = map(int,input().split())
l = sorted([list(map(int,input().split())) for _ in range(n)])[::-1]
a,b = l[0]
cou = 0
if b>=h:
  print(1)
  exit()
l1 = sorted([i for j,i in l[1:]])[::-1]
for k in l1:
  if a<k:
    cou += 1
    h -= k
    if h<=0:
      print(cou)
      exit()
    elif h-b<=0:
      print(cou+1)
      exit()
h -= b
cou += 1
if h<=0:
  print(cou)
else:
  t = -(-h//a)
  print(cou+t)

Solution (Python):
n,h = map(int,input().split())
A=[]
B=[]
for i in range(n):
    a,b = map(int,input().split())
    A.append(a)
    B.append(b)
A.sort(reverse=True)
B.sort(reverse=True)
maxA = A[0]
cnt=0
for i in range(n):
    if B[i]>=maxA:
        h-=B[i]
        cnt+=1
        if h<=0:
            print(cnt)
            break
    else:
        cnt+=-(-h//maxA)
        print(cnt)
        break
else:
    cnt+=-(-h//maxA)
    print(cnt)

Solution (Python):
import heapq

n, h = map(int, input().split())

hq = []

for i in range(n):
    a, b = map(int, input().split())
    heapq.heappush(hq, [-a, float("inf")])
    heapq.heappush(hq, [-b, 1])

ans = 0
while h > 0:
    damage, cnt = heapq.heappop(hq)
    damage = -damage

    if cnt == float("inf"):
        ans += (h + damage - 1) // damage
        h = 0
        heapq.heappush(hq, [-damage, float("inf")])
    else:
        ans += 1
        h -= damage

print(ans)