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):
import math


def find_argmax(num_list):
    argmax = sorted(enumerate(num_list), key=lambda x:x[1])[-1][0]
    return argmax


def find_all_more_than(threshold, num_list):
    indices = [
        idx
        for idx, num in enumerate(num_list) 
        if num > threshold
    ]
    return indices


def read_input():
    initial_inputs = input().split(" ")
    N = int(initial_inputs[0])
    H = int(initial_inputs[1])
    a_list = []
    b_list = []
    for _ in range(N):
        inputs = input().split(" ")
        a = int(inputs[0])
        b = int(inputs[1])
        a_list.append(a)
        b_list.append(b)
    return N, H, a_list, b_list



def searchA(N, H, a_list, b_list):
    
    used_indices = [ False for b in b_list]

    
    search_area = [ b for b in b_list ]

    
    times_count = 0
    
    while H > 0:
        
        idx = find_argmax(search_area)

        
        if used_indices[idx]:
            
            rest_count = math.ceil(H / search_area[idx])
            return times_count + rest_count

        
        H -= search_area[idx]

        
        search_area[idx] = a_list[idx]
        used_indices[idx] = True
        
        
        times_count += 1

    return times_count


def searchB(N, H, a_list, b_list):
    
    used_indices = [ False ] * N

    
    search_area = [ b for b in b_list ]

    
    times_count = 0

    
    higher_b_indices = find_all_more_than(max(a_list), b_list)
    higher_b_list = [ b_list[idx] for idx in higher_b_indices ]

    for b in reversed(sorted(higher_b_list)):
        if not H > 0:
            return times_count

        
        H -= b
        times_count += 1

    
    for idx in higher_b_indices:
        
        search_area[idx] = a_list[idx]
        used_indices[idx] = True

    while H > 0:
        
        idx = find_argmax(search_area)

        
        if used_indices[idx]:
            
            rest_count = math.ceil(H / search_area[idx])
            return times_count + rest_count

        
        H -= search_area[idx]
        times_count += 1

        
        search_area[idx] = a_list[idx]
        used_indices[idx] = True
        
    return times_count



def searchC(N, H, a_list, b_list):
    
    times_count = 0

    
    max_a = max(a_list)
    higher_b_indices = find_all_more_than(max_a, b_list)
    higher_b_list = [ b_list[idx] for idx in higher_b_indices ]

    for b in reversed(sorted(higher_b_list)):
        if not H > 0:
            return times_count

        
        H -= b
        times_count += 1

    
    rest_count = math.ceil(H / max_a)
    return times_count + rest_count


def main():
    
    N, H, a_list, b_list = read_input()

    
    times_count = searchC(N, H, a_list, b_list)

    
    print(times_count)
    

if __name__ == '__main__':
    main()

Solution (Python):
import sys
import heapq
import re
from itertools import permutations
from bisect import bisect_left, bisect_right
from collections import Counter, deque
from fractions import gcd
from math import factorial, sqrt, ceil
from functools import lru_cache, reduce
INF = 1 << 60
MOD = 1000000007
sys.setrecursionlimit(10 ** 7)


class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self, x):
        return -self.parents[self.find(x)]

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def group_count(self):
        return len(self.roots())

    def all_group_members(self):
        return {r: self.members(r) for r in self.roots()}

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())

def is_prime(n):
    if n == 1:
        return False
    for i in range(2,int(n**0.5)+1):
        if n % i == 0:
            return False
    return True




def warshall_floyd(d, n):
    
    for k in range(n):
        for i in range(n):
            for j in range(n):
                d[i][j] = min(d[i][j],d[i][k] + d[k][j])
    return d



def dijkstra_heap(s, edge, n):
    
    d = [10**20] * n
    used = [True] * n 
    d[s] = 0
    used[s] = False
    edgelist = []
    for a,b in edge[s]:
        heapq.heappush(edgelist,a*(10**6)+b)
    while len(edgelist):
        minedge = heapq.heappop(edgelist)
        
        if not used[minedge%(10**6)]:
            continue
        v = minedge%(10**6)
        d[v] = minedge//(10**6)
        used[v] = False
        for e in edge[v]:
            if used[e[1]]:
                heapq.heappush(edgelist,(e[0]+d[v])*(10**6)+e[1])
    return d


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 lcm(x, y):
    return (x * y) // gcd(x, y)


def lcm_list(numbers):
    return reduce(lcm, numbers, 1)


def gcd_list(numbers):
    return reduce(gcd, numbers)






def eratosthenes(limit):
    A = [i for i in range(2, limit+1)]
    P = []

    while True:
        prime = min(A)
        
        if prime > sqrt(limit):
            break
            
        P.append(prime)
            
        i = 0
        while i < len(A):
            if A[i] % prime == 0:
                A.pop(i)
                continue
            i += 1
            
    for a in A:
        P.append(a)
            
    return P


def permutation_with_duplicates(L):

    if L == []:
        return [[]]

    else:
        ret = []

        
        S = sorted(set(L))

        for i in S:

            data = L[:]
            data.remove(i)

            for j in permutation_with_duplicates(data):
                ret.append([i] + j)

        return ret



n, h = map(int, input().split())
b = [0 for i in range(n)]
a_max = 0
for i in range(n):
    c, d = map(int, input().split())
    a_max = max(a_max, c)
    b[i] = d
b.sort(reverse=True)
for i in range(1, n):
    b[i] += b[i - 1]
if a_max >= h or b[0] >= h:
    print(1)
else:
    ans = -(-h // a_max)
    for i in range(n):
        if b[i] >= h:
            ans = min(ans, i + 1)
            break
        ans = min(ans, i + 1 -(-(h - b[i]) // a_max))
    print(ans)

Solution (Python):
import numpy as np
import functools
import math
import scipy
import fractions
import itertools

def solve():
    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())
    a.sort(reverse = True)
    b.sort(reverse = True)
    ans = 0
    m = max(a)
    bit = 0
    for i in range(n):
        if b[i] > m:
            h -= b[i]
            ans += 1
        if h <= 0:
            print(ans)
            bit = 1
            break
    if bit == 0:
        ans += math.ceil(h/m)
        print(ans)
    return 0
 
if __name__ == "__main__":
    solve()

Solution (Python):
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**7)
from collections import Counter, deque
from collections import defaultdict
from itertools import combinations, permutations, accumulate, groupby, product
from bisect import bisect_left,bisect_right
from heapq import heapify, heappop, heappush
from math import floor, ceil,pi
from operator import itemgetter
def I(): return int(input())
def MI(): return map(int, input().split())
def LI(): return list(map(int, input().split()))
def LI2(): return [int(input()) for i in range(n)]
def MXI(): return [[LI()]for i in range(n)]
def printns(x): print('\n'.join(x))
def printni(x): print('\n'.join(list(map(str,x))))
inf = 10**17
mod = 10**9 + 7


n,h=MI()
A=[]
B=[]
for i in range(n):
    a,b=MI()
    A.append(a)
    B.append(b)

A.sort(reverse=True)
B.sort(reverse=True)
ace=A[0]
throw=[]
for b in B:
    if b>ace:
        throw.append(b)
if h>sum(throw):
    slash1=ceil((h-sum(throw))/ace)
    h-=ace*slash1
    ans=slash1+len(throw)
else:
    for i in range(len(throw)):
        h-=throw[i]
        if h<=0:
            ans=i+1
            break
print(ans)

Solution (Python):
def main():
  n,h=map(int,input().split())
  ab=[list(map(int,input().split())) for _ in range(n)]
  amax=max([a for a,b in ab])
  b=[b for a,b in ab if b>amax]
  b.sort(reverse=True)
  ans=0
  sumb=sum(b)
  if h<sumb:
    d=0
    while d<h:
      d+=b[ans]
      ans+=1
    print(ans)
  else:
    d=h-sumb
    ans=len(b)+(d+amax-1)//amax 
    print(ans)
if __name__=='__main__':
  main()

Solution (Python):
N, H = map(int, input().split())
AB = [[int(i) for i in input().split()] for _ in range(N)]
A, B = map(list, zip(*AB))
B.sort()
X = max(A)
S = sum(B)

cnt = 0
if H > S:
    cnt += (H - S) // X
    H = H - X * cnt
if H > 0:
    for b in B[::-1]:
        H -= max(b, X)
        cnt += 1
        if H <= 0: break
while H > 0:
    H -= X
    cnt += 1
print(cnt)

Solution (Python):
n , h = map(int,input().split())
p = []
q = []
for i in range(n):
    a , b = map(int,input().split())
    p.append(a)
    q.append(b)
A = max(p)
q.sort(reverse=True)
ans = 0
for i in range(n):
    ans += 1
    h -= max(q[i],A)
    if h <= 0:
        print(ans)
        exit()

ans += -(-h//A)
print(ans)

Solution (Python):
from math import ceil
N,H=map(int,input().split())
a=[]
Amax=0
Bsum=0

for _ in range(N):
    A,B=map(int,input().split())
    Amax=max(A,Amax)
    a.append([B,A])
a.sort(reverse=True)

for i in range(N):
    Bsum+=max(Amax,a[i][0])

if H>Bsum:
    print(ceil((H-Bsum)/Amax)+N)
else:
    n=0
    while H>0:
        H-=max(Amax,a[n][0])
        n+=1
    print(n)

Solution (Python):
MAX = (10 ** 9) * (-1)
def solve(N, H, a, b):
    import heapq
    import math
    
    max_a = max(a)
    max_a_index =[]
    for i in range(N):
        if(a[i] == max_a):
            max_a_index.append(i)

    minimum_b_in_max_a_index = -1
    minimum_b_in_max_a = MAX
    for i in max_a_index:
        temp_b = b[i]
        if(temp_b >= minimum_b_in_max_a):
            minimum_b_in_max_a = temp_b
            minimum_b_in_max_a_index = i
    
    main_sword_index = minimum_b_in_max_a_index
    main_sword_a = a.pop(main_sword_index)
    main_sword_b = b.pop(main_sword_index) * (-1)

    heapq.heapify(b)
    answer = 0

    
    while len(b) > 0:
        new_sword = heapq.heappop(b) * (-1)
        if(new_sword < main_sword_a):
            break
        else:
            H -= new_sword
            answer += 1
            if(H <= 0):
                return answer

    

    if(H <= main_sword_b):
            
            answer += 1
    else:
        H -= main_sword_b
        answer += 1
        answer += (math.ceil(H / main_sword_a))
    return answer


def main():
    N, H = map(int, input().split())
    swords = []
    a = [0] * N
    b = [0] * N
    for i in range(N):
        
        X, Y = map(int, input().split())
        a[i] = X
        b[i] = Y * (-1)
    
    print(solve(N, H, a, b)) 
    


main()

Solution (Python):
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())
target = max(A)
ans = 0
B.sort(reverse=True)
for i in B:
    if i >= target:
        H -= i
        ans += 1
    if H <= 0:
        print(ans)
        exit()
print(ans-(-H//target))

Solution (Python):
def main():
    N, H = map(int, input().split())
    katana = []
    for i in range(N):
        a, b = map(int, input().split())
        katana.append((a, b))
    cnt = 0
    num = 0
    
    k = sorted(katana, key=lambda x:x[1], reverse=True)
    ks = sorted(katana, key=lambda x:x[0], reverse=True)
    
    for i in range(N):
        if(k[i][1] > ks[0][0]):
            H -= k[i][1]
            cnt += 1
            if(H <= 0):
                break
            
        else:
            break    
    
    if(H > 0):
        if(H%ks[0][0] == 0):
            cnt += H//ks[0][0]
        else:
            cnt += H//ks[0][0]+1
    
    print(cnt)
       
main()

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

a=[]
b=[]
damege=0
count=0

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

if N>1:
    b=sorted(b,reverse=True)

i=0
A=max(a)
while i<N and b[i]>A and damege<H:
    damege+=b[i]
    i+=1
    count+=1
count+=-(-max(0,H-damege)//A)

print(count)

Solution (Python):
import math
N,H=map(int,input().split())
a=[0]*N
b=[0]*N
for i in range(N):
  a[i],b[i] = map(int,input().split())
  
p=0
cnt=0
nokori=0
b.sort(reverse=True)
maxi=max(a)

for th in b:
  if p>=H:
    break
  else:
    if th>maxi:
      p += th
      cnt+=1
else:
  nokori= math.ceil((H-p)/maxi)
print(cnt+nokori)

Solution (Python):
N,H = map(int,input().split())
ab = [list(map(int,input().split())) for i in range(N)]
ab.sort(key=lambda x: x[1])
ab.sort(reverse=True,key=lambda x: x[0])
A,B = ab[0]
ab.sort(reverse=True,key=lambda x: x[1])
ans = 0
i=0
while i<N:
    if H<=0:
        break
    
    if ab[i][1]>=A:
        H-=ab[i][1]
        i+= 1
        ans += 1
        continue
    else:
        break
from math import ceil
if H>=0:
    ans += ceil(H/A)
print(ans)

Solution (Python):

import sys
sys.setrecursionlimit(1 << 25)
read = sys.stdin.readline
ra = range
enu = enumerate


def read_ints():
    return list(map(int, read().split()))


def read_a_int():
    return int(read())


def read_tuple(H):
    '''
    H is number of rows
    '''
    ret = []
    for _ in range(H):
        ret.append(tuple(map(int, read().split())))
    return ret


def read_col(H):
    '''
    H is number of rows
    A列、B列が与えられるようなとき
    ex1)A,B=read_col(H)    ex2) A,=read_col(H) 
    '''
    ret = []
    for _ in range(H):
        ret.append(list(map(int, read().split())))
    return tuple(map(list, zip(*ret)))


def read_matrix(H):
    '''
    H is number of rows
    '''
    ret = []
    for _ in range(H):
        ret.append(list(map(int, read().split())))
    return ret
    


MOD = 10**9 + 7
INF = 2**31  

from collections import defaultdict, Counter, deque
from operator import itemgetter
from itertools import product, permutations, combinations
from bisect import bisect_left, bisect_right  








N, H = read_ints()
A, B = read_col(N)
A_ma = max(A)

B.sort()
B_use = B[bisect_right(B, A_ma):]
B_use = list(reversed(B_use))

ans = 0
dmg = 0
for b in B_use:
    if dmg >= H:
        break
    ans += 1
    dmg += b

H -= dmg
if H > 0:
    ans += (H - 1) // A_ma + 1

print(ans)

Solution (Python):
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())

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

def count(n):
    damage=0
    cnt=0
    for i in range(n):
        cnt+=1
        damage+=b[i]
        if damage>=H:
            return cnt
    
    cnt -= (-(H-damage))//a[0]
    return cnt

for i in range(N):
    if b[i]>a[0]:
        continue
    else:
        print(count(i))
        exit()
print(count(N))

Solution (Python):
from math import ceil
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.sort(reverse=True)
sw=max(A)
cnt=0
dam=0
for i in range(N):
    if B[i]<sw:
        break
    cnt+=1
    dam+=B[i]
    if dam>=H:
        print(cnt)
        exit()
cnt+=ceil((H-dam)/sw)
print(cnt)

Solution (Python):
import bisect
from math import ceil
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=sorted(A)
B=sorted(B)

idx=bisect.bisect_right(B,A[-1])
throw=sum(B[idx:])
if throw<=H:
    ans=N-idx
    res=H-throw
    ans+=ceil(res/A[-1])
    
else:
    res=H
    ans=0
    for i in range(N):
        ans+=1
        res-=B[-(i+1)]
        if res<=0:
            break
print(ans)

Solution (Python):
def main():
    import sys
    input = sys.stdin.readline

    N, H = map(int, input().split())

    bs = []
    a_mx = -1
    for _ in range(N):
        a, b = map(int, input().split())
        a_mx = max(a_mx, a)
        bs.append(b)

    bs = [b for b in bs if b > a_mx]
    bs.sort(reverse=True)

    ans = 0
    for b in bs:
        H -= b
        ans += 1
        if H <= 0:
            break
    if H > 0:
        ans += (H + a_mx - 1) // a_mx

    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
from math import ceil
n, h = map(int, input().split())
cut = set()
throw = []

for _ in range(n):
    a, b = map(int, input().split())
    cut.add(a)
    throw.append(b)

throw.sort(reverse=True)
ans = 0
m_cut = max(cut)

for t in throw:
    if t > m_cut:
        ans += 1
        h -= t
    if h <= 0:
        break

if h > 0:
    ans += ceil(h / m_cut)

print(ans)

Solution (Python):
n,h=map(int,input().split())
ab=[]
ans=0
for i in range(n):
  aa,bb=map(int,input().split())
  ab.append([aa,bb])

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

for a,b in ab:
  if b>katana:
    cnt+=1

for i in range(cnt):
  if h<=0:break
  h-=ab[i][1]
  ans+=1
if h>0:
  ans+=(h+katana-1)//katana
print(ans)

Solution (Python):
n,h=map(int,input().split())
ab=[]
ans=0
for i in range(n):
  aa,bb=map(int,input().split())
  ab.append([aa,bb])

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

for a,b in ab:
  if b>katana:
    cnt+=1

for i in range(cnt):
  if h<=0:break
  h-=ab[i][1]
  ans+=1
if h>0:
  ans+=(h-1)//katana+1
print(ans)

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

Solution (Python):
from collections import Counter,defaultdict,deque
from heapq import heappop,heappush,heapify
import sys,bisect,math,itertools,fractions
sys.setrecursionlimit(10**8)
mod = 10**9+7
INF = float('inf')
def inp(): return int(sys.stdin.readline())
def inpl(): return list(map(int, sys.stdin.readline().split()))

n,m = inpl()
ab = [inpl() for _ in range(n)]
su = sum(x[1] for x in ab)
mx = max(x[0] for x in ab)
ab.sort(key = lambda x:x[1], reverse = True)
res = 0
for i in range(n):
    if ab[i][1] > mx:
        m -= ab[i][1]
        res += 1
    else:
        break
    if m <= 0:
        print(res)
        quit()
print(res + (m + mx - 1)//mx)

Solution (Python):
from bisect import bisect_right
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 = sorted(A,reverse=True)
B = sorted(B)
a = A[0]
ind = bisect_right(B,a)
cnt = 0
flag = 0
for i in range(N-1,ind-1,-1):
    H -= B[i]
    cnt += 1
    if H<=0:
        flag = 1
        break
if flag==0:
    k = H//a
    if H%a>0:
        k += 1
    cnt += k
print(cnt)

Solution (Python):


import sys
input= lambda: sys.stdin.readline().rstrip()
def pin(type=int):return map(type,input().split())
def tupin(t=int):return tuple(pin(t))

def resolve():
    N,HP=pin()
    weapon=[tupin() for _ in range(N)]
    weapon.sort(key=lambda x:x[0])
    a=weapon[-1][0]
    ans=0
    weapon.sort(key=lambda x:x[1],reverse=True)
    for w in weapon:
        if w[1]>a:
            HP-=w[1];ans+=1
            if HP<=0:break
    if HP>0:
        ans+=((HP-1)//a)+1
    print(ans)

resolve()

Solution (Python):
n,h=map(int,input().split())
ab=[list(map(int,input().split())) for i in range(n)]
ab.sort(reverse=True,key=lambda x:x[1])

a_max=0
for a,b in ab:
  a_max=max(a,a_max)

cnt=0
damage=0
for a,b in ab:
  if damage>=h:
    print(cnt)
    exit()
  if b<=a_max:
    break

  cnt+=1
  damage+=b

zan=h-damage
cnt+=(zan+a_max-1)//a_max
print(cnt)

Solution (Python):
N,H = map(int,input().split())
A = [-1 for _ in range(N)]
B = [-1 for _ in range(N)]
for i in range(N):
    a,b = map(int,input().split())
    A[i] = a
    B[i] = b
MA = max(A)
B.sort(reverse=True)
ans = 0

for i in range(N):
    if H > 0 and B[i] > MA:
        H -= B[i]
        ans += 1
    else:
        break
if H > 0:
    ans += (H+MA-1)//MA
print(ans)

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

a = max(a)
b.sort(reverse=True)
ans = 0
for i in b:
    if i<=a:
        ans += (h+a-1)//a
        print(ans)
        break
    h -= i
    ans += 1
    if h<=0:
        print(ans)
        break
else:
    ans += (h+a-1)//a
    print(ans)

Solution (Python):
def main():
    N, H = (int(i) for i in input().split())
    AB = [[int(i) for i in input().split()] for j in range(N)]
    AB.sort()
    maxA = AB[-1][0]
    maxA_B = AB[-1][1]
    AB.pop()
    AB = [[a, b] for a, b in AB if maxA <= b]
    AB.sort(key=lambda p: p[1])
    ans = 0
    while len(AB) and H > maxA_B:
        ans += 1
        H -= AB.pop()[1]
    
    if H > maxA_B:
        times = 0--(H-maxA_B)//maxA
        ans += times
        H -= times*maxA
    
    if H > 0:
        H -= maxA_B
        ans += 1
    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):

import sys
sys.setrecursionlimit(1 << 25)
read = sys.stdin.readline
ra = range
enu = enumerate


def read_ints():
    return list(map(int, read().split()))


def read_a_int():
    return int(read())


def read_tuple(H):
    '''
    H is number of rows
    '''
    ret = []
    for _ in range(H):
        ret.append(tuple(map(int, read().split())))
    return ret


def read_col(H):
    '''
    H is number of rows
    A列、B列が与えられるようなとき
    ex1)A,B=read_col(H)    ex2) A,=read_col(H) 
    '''
    ret = []
    for _ in range(H):
        ret.append(list(map(int, read().split())))
    return tuple(map(list, zip(*ret)))


def read_matrix(H):
    '''
    H is number of rows
    '''
    ret = []
    for _ in range(H):
        ret.append(list(map(int, read().split())))
    return ret
    


MOD = 10**9 + 7
INF = 2**31  

from collections import defaultdict, Counter, deque
from operator import itemgetter
from itertools import product, permutations, combinations
from bisect import bisect_left, bisect_right  








N, H = read_ints()
A, B = read_col(N)
A_ma = max(A)

B.sort()
B_use = B[bisect_right(B, A_ma):]
B_use = list(reversed(B_use))

ans = 0
dmg = 0
for b in B_use:
    if dmg >= H:
        break
    ans += 1
    dmg += b

H -= dmg
if H > 0:
    ans += (H - 1) // A_ma + 1

print(ans)

Solution (Python):
n,h=map(int,input().split())
x=[0]*n
y=0
for i in range(n):
    a,b=map(int,input().split())
    y=max(y,a)
    x[i]=b
cnt=0
x.sort(reverse=1)
for i in x:
    if i>y:
        cnt+=1
        h-=i
    if h<=0:
        print(cnt)
        exit()
print(cnt+(h+y-1)//y)

Solution (Python):
from math import ceil


def main():
    n, h = map(int, input().split())
    attack = []
    for _ in range(n):
        a, b = map(int, input().split())
        attack.append([a, 1])
        attack.append([b, 0])
    answer = 0
    attack.sort(key=lambda x: x[0], reverse=True)
    for a, t in attack:
        if h <= 0:
            break
        if t:
            answer += ceil(h / a)
            h = 0
        else:
            answer += 1
            h -= a
    print(answer)


if __name__ == '__main__':
    main()

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

N, H = map(int, input().split())
AB = [tuple(map(int, input().split())) for _ in range(N)]

tmp = 0
for a, b in AB:
    tmp = max(tmp, a)

AB.sort(key = lambda x: x[1], reverse = True)

count = 0
for a, b, in AB:
    if b > tmp:
        H -= b
        count += 1
        if H <= 0:
            print (count)
            exit()
    else:
        break

count += (H + tmp - 1) // tmp
print (count)

Solution (Python):
def examA():
    C = [SI()for _ in range(3)]
    ans = C[0][0]+C[1][1]+C[2][2]
    print(ans)
    return

def examB():
    N, M = LI()
    P = [0]*N
    S = [LSI()for _ in range(M)]
    pena = 0
    ac = set()
    for p,s in S:
        p = int(p)-1
        if s=="WA":
            P[p] += 1
        else:
            if p in ac:
                continue
            ac.add(p)
            pena += P[p]

    print(len(ac),pena)
    return

def examC():
    W, H, N = LI()
    lx, rx, ly, ry = 0, W, 0, H
    A = [LI()for _ in range(N)]
    for x,y,a in A:
        if a==1:
            lx = max(lx,x)
        elif a==2:
            rx = min(rx,x)
        elif a==3:
            ly = max(ly,y)
        elif a==4:
            ry = min(ry,y)
    ans = max(0,rx-lx)*max(0,ry-ly)
    print(ans)
    return

def examD():
    N, H = LI()
    B = [0]*N
    maxa = 0
    ans = 0
    for i in range(N):
        a, B[i] = LI()
        if a>maxa:
            maxa = a
    B.sort(reverse=True)
    for b in B:
        if b<maxa:
            break
        H -= b
        ans += 1
        if H<=0:
            print(ans)
            return
    ans += -(-H//maxa)
    print(ans)
    return

def examE():
    ans = 0
    print(ans)
    return

def examF():
    ans = 0
    print(ans)
    return

import sys,bisect,itertools,heapq,math,random
from copy import deepcopy
from heapq import heappop,heappush,heapify
from collections import Counter,defaultdict,deque
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
def I(): return int(readline())
def LI(): return list(map(int,readline().split()))
def LSI(): return list(map(str,sys.stdin.readline().split()))
def LS(): return sys.stdin.readline().split()
def SI(): return sys.stdin.readline().strip()
global mod,mod2,inf,alphabet,_ep
mod = 10**9 + 7
mod2 = 998244353
inf = 10**18
_ep = 10**(-12)
alphabet = [chr(ord('a') + i) for i in range(26)]

sys.setrecursionlimit(10**7)

if __name__ == '__main__':
    examD()

"""
142
12 9 1445 0 1
asd dfg hj o o
aidn
"""

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)

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

ans = 0
for b in B:
    if b <= mxA or H <= 0:
        break
    H -= b
    ans += 1

if H > 0:
    ans += -(-H // mxA)

print(ans)

Solution (Python):
import math
n,h=map(int,input().split())
ans=0
m=0
b=[]
for i in range(n):
    a,B=map(int,input().split())
    b.append(B)
    m=max(m,a)
b=sorted(b,reverse=True)
for i in range(len(b)):
    if b[i]<m:
        break
    else:
        h-=b[i]
        ans=i+1
        if h<1:
            print(ans)
            exit()
print(ans+math.ceil(h/m))

Solution (Python):
n,h=map(int,input().split())
ab=[list(map(int,input().split()))for _ in range(n)]
c=max([a[0] for a in ab])
d=[b[1] for b in ab if b[1]>c]
d.sort()
ans=0
while len(d)>0:
    h-=d.pop()
    ans+=1
    if h<=0:
        print(ans)
        exit()
f=(h+c-1)//c
print(ans+f)

Solution (Python):
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())
p=max(a)
b.sort(reverse=True)
ans=0
for i in range(n):
    if b[i]>=p:
        ans+=1
        h-=b[i]
        if h<=0:
            print(ans)
            exit()
x=(-h//p)*(-1)
ans+=x
print(ans)

Solution (Python):
N, H = map(int, input().split())
X = [list(map(int, input().split())) for _ in range(N)]

a, b = zip(*((a, b) for a, b in X))
am = max(a)
b = sorted(b, reverse=True)

ans = 0
h = H
for v in b:
    if v > am:
        h -= v
        ans += 1

    if h <= 0:
        break
        
if h > 0:
    ans += -(-h // am)

print(ans)

Solution (Python):
import sys
from math import ceil

def read():
    return sys.stdin.readline().rstrip()

def main():
    n, h = map(int, read().split())
    a = 0
    b = [0] * n
    c = 0
    for i in range(n):
        ai, bi = map(int, read().split())
        a = max(ai, a)
        b[i] = bi
    for d in sorted([bi for bi in b if bi > a] + [a], reverse=True):
        h -= d
        c += 1
        if h <= 0:
            break
    else:
        c += ceil(h / a)
    print(c)

if __name__ == '__main__':
    main()

Solution (Python):
n,h=map(int,input().split())
AB = [list(map(int, input().split())) for i  in range(n)]
AB = sorted(AB, key=lambda x:x[1])
ans = 0

a = sorted(AB)[-1][0]
for i in range(len(AB)):
  if len(AB) <= 0 or h <= 0:
    break
  b = AB.pop(-1)[1]
  h -= b if b > a else a
  ans += 1

if h > 0:
  ans += (h+a-1)//a

print(ans)

Solution (Python):
N, H = map(int, input().split())
ab = [list(map(int, input().split())) for i in range(N)]

max_a = sorted(ab, key=lambda x: -x[0])[0][0]
bs = sorted([b for a,b in ab if b > max_a], reverse=True)
sum_bs = sum(bs)

if H <= sum_bs:
    for i in range(len(bs)):
        H -= bs[i]
        if H <= 0:
            print(i+1)
            exit()
else:
    H -= sum_bs
    print((H+max_a-1)//max_a + len(bs))

Solution (Python):
import math
n , h = map(int,input().split())
max = 0
b = []
c = 0
for i in range(n):
    a , b1 = map(int,input().split())
    if a > max:
        max = a
    b.append(b1)
b.sort(reverse = True)
b.append(0)
i=0
while h > 0 and b[i]>max:
    h-=b[i]
    i+=1
    c+=1
if h > 0:
    c += math.ceil(h/max)
print(c)

Solution (Python):
n,h=map(int,input().split())
att=[]
for i in range(n):
    att.append(list(map(int,input().split())))
att=sorted(att,reverse=True)

sel=[]
M=att[0][0]
for i in range(n):
    if att[i][1]>M:
        sel.append(att[i])

sum=0
turn=0
att=sorted(sel,reverse=True,key=lambda x: x[1])

for i in range(len(att)):
    sum += att[i][1]
    turn += 1
    if sum >= h:
        break
if sum < h:
    turn += (h-sum)//M
    if (h-sum)%M!=0:
        turn += 1
print(turn)