Problem:
 Score : 300 points    Problem Statement A programming competition site AtCode provides algorithmic problems.
Each problem is allocated a score based on its difficulty.
Currently, for each integer i between 1 and D (inclusive), there are p_i problems with a score of 100i points.
These p_1 + … + p_D problems are all of the problems available on AtCode.  A user of AtCode has a value called total score .
The total score of a user is the sum of the following two elements:   Base score: the sum of the scores of all problems solved by the user.  Perfect bonuses: when a user solves all problems with a score of 100i points, he/she earns the perfect bonus of c_i points, aside from the base score (1 ≤ i ≤ D) .   Takahashi, who is the new user of AtCode, has not solved any problem.
His objective is to have a total score of G or more points.
At least how many problems does he need to solve for this objective?      Constraints  1 ≤ D ≤ 10  1 ≤ p_i ≤ 100  100 ≤ c_i ≤ 10^6  100 ≤ G  All values in input are integers.  c_i and G are all multiples of 100 .  It is possible to have a total score of G or more points.         Input Input is given from Standard Input in the following format:  D  G  p_1  c_1  :  p_D  c_D       Output Print the minimum number of problems that needs to be solved in order to have a total score of G or more points. Note that this objective is always achievable (see Constraints).        Sample Input 1 2 700
3 500
5 800      Sample Output 1 3  In this case, there are three problems each with 100 points and five problems each with 200 points. The perfect bonus for solving all the 100 -point problems is 500 points, and the perfect bonus for solving all the 200 -point problems is 800 points. Takahashi's objective is to have a total score of 700 points or more.  One way to achieve this objective is to solve four 200 -point problems and earn a base score of 800 points. However, if we solve three 100 -point problems, we can earn the perfect bonus of 500 points in addition to the base score of 300 points, for a total score of 800 points, and we can achieve the objective with fewer problems.       Sample Input 2 2 2000
3 500
5 800      Sample Output 2 7  This case is similar to Sample Input 1, but the Takahashi's objective this time is 2000 points or more. In this case, we inevitably need to solve all five 200 -point problems, and by solving two 100 -point problems additionally we have the total score of 2000 points.       Sample Input 3 2 400
3 500
5 800      Sample Output 3 2  This case is again similar to Sample Input 1, but the Takahashi's objective this time is 400 points or more. In this case, we only need to solve two 200 -point problems to achieve the objective.       Sample Input 4 5 25000
20 1000
40 1000
50 1000
30 1000
1 1000      Sample Output 4 66  There is only one 500 -point problem, but the perfect bonus can be earned even in such a case.

Solution (Python):
import math

D, G = [int(i) for i in input().split()]
problems = []
for i in range(D):
    p, c = [int(_) for _ in input().split()]
    bit = 0
    problems.append([p, c])

ans = 1001
for i in range(2**D):
    score = 0
    p_num = 0
    for j, p in enumerate(problems):
        if i >> j & 1:
            score += p[0] * 100 * (j + 1) + p[1]
            p_num += p[0]
    if score < G:
        rest = G - score
        for j in range(D-1, -1, -1):
            if i >> j & 1:
                continue
            n = math.ceil(rest / (100 * (j + 1)))
            if n <= problems[j][0] - 1:
                rest -= n * 100 * (j + 1)
                p_num += n
                break
            rest -= problems[j][0] * 100 * (j + 1)
            p_num += problems[j][0]
        if rest <= 0:
            ans = min(ans, p_num)
    else:
        ans = min(ans, p_num)
print(ans)

Solution (Python):
d,g=map(int,input().split())
pc_=[list(map(int,input().split())) for _ in range(d)]
pc=[[(i+1)*100,pc[0],pc[1]] for i,pc in enumerate(pc_)]
n=d
ans=1000
for i in range(2**n):
  all_ac=[]
  no_ac=[]
  for j in range(n):
    if ((i>>j) & 1):
      all_ac.append(j)
    else:
      no_ac.append(j)
  score=sum([pc[j][2]+pc[j][0]*pc[j][1] for j in all_ac])
  n_ac=sum([pc[j][1] for j in all_ac])
  tmp=g-score
  while no_ac and tmp>0:
    a=no_ac.pop()
    i,p,c=pc[a]
    if tmp<=i*(p-1):
      n_ac+=(tmp+i-1)//i
      tmp=0
    else:
      n_ac+=p-1
      tmp-=i*(p-1)
  if tmp<=0:
    ans=min(n_ac,ans)
print(ans)

Solution (Python):
import sys
sys.setrecursionlimit(10 ** 9)

def int1(x): return int(x) - 1
def II(): return int(input())

def MI(): return map(int, input().split())
def MI1(): return map(int1, input().split())

def LI(): return list(map(int, input().split()))
def LI1(): return list(map(int1, input().split()))
def LLI(rows_number): return [LI() for _ in range(rows_number)]

def SMI(): return input().split()
def SLI(): return list(input())

def printlist(lst, k=' '): print(k.join(list(map(str, lst))))
INF = float('inf')








def solve():
    D, G = MI()
    P = []
    C = []
    for _ in range(D):
        p, c = MI()
        P.append(p)
        C.append(c)

    ans = INF
    for i in range(1 << D):
        bag = []
        cag = []
        for j in range(D):
            if (i >> j) & 1:
                bag.append(j)
            else:
                cag.append(j)
        
        score = 0
        cnt = 0
        for b in bag:
            score += (b+1) * 100 * P[b] + C[b]
            cnt += P[b]
        
        if score >= G:
            ans = min(ans, cnt)
            
        else:
            c = cag[-1]
            for i in range(P[c]):
                score += (c+1) * 100
                cnt += 1
                if score >= G:
                    ans = min(ans, cnt)
                    
                    break

    print(ans)


if __name__ == '__main__':
    solve()

Solution (Python):
def resolve():
    d,g = map(int,input().split())
    pc = [list(map(int, input().split())) for _ in range(d)]
    ans = 10**9
    for i in range(2**d):
        count = 0
        total = 0
        nokori = [1 for _ in range(d)]
        for j in range(d):
            if (i>>j & 1):
                total += pc[j][0] * (j+1)* 100 + pc[j][1]
                count += pc[j][0]
                nokori[j] = 0
        if total >= g:
            ans = min(ans, count)
        else:
            for k in reversed(range(len(nokori))):
                if nokori[k] == 0:
                    continue
                else:
                    if total + (pc[k][0]-1) * (k+1) *100 >= g:
                        count += (((g-total) + (k+1)*100)-1)//((k+1)*100)
                        ans = min(ans, count)
                        break
                    else:
                        total += (pc[k][0]-1) * (k+1) *100
                        count += (pc[k][1]-1)
    print(ans)
resolve()

Solution (Python):
d, g = map(int, input().split())

p, c = [], []

for i in range(d):
    p_tmp, c_tmp = map(int, input().split())
    p.append(p_tmp)
    c.append(c_tmp)

ans = 10 ** 18

for bit in range(1 << d):
    solve = 0
    score = 0
    for i in range(d):
        if bit & (1 << i):
            score += 100 * (i + 1) * p[i]
            score += c[i]
            solve += p[i]
        if score >= g:
            ans = min(ans, solve)
    else:
        if score < g:
            tmp = (1 << d) - 1
            not_bit = bit ^ tmp
            digit = 0
            while not_bit != 0:
                digit += 1
                not_bit = not_bit >> 1
            for j in range(p[digit - 1]):
                score += digit * 100
                solve += 1
                if score >= g:
                    ans = min(ans, solve)
                    break

print(ans)

Solution (Python):


import math
import re
import numpy as np
import copy

S = input().split(" ")
D = int(S[0])
G = int(S[1])

p_n = []
c_n = []

for i in range(D):
    line = input().split(" ")
    p = int(line[0])
    c = int(line[1])
    p_n.append(p)
    c_n.append(c)


ans = 1000000


def CombiBonus(flag):
    
    if len(flag) == D:
        
        CalcMin(flag)

    else:
        
        non_use = flag + "0"
        use = flag + "1"
        CombiBonus(non_use)
        CombiBonus(use)


def CalcMin(flag):
    global ans

    

    
    unsolved = copy.copy(p_n)
    
    score = 0
    
    cnt = 0

    
    for i in range(D):
        if flag[i] == "1":
            unsolved[i] = 0
            score += (i+1)*p_n[i]*100
            score += c_n[i]
            cnt += p_n[i]

    
    current_d = D-1
    
    while score < G:
        
        if unsolved[current_d] > 1:
            unsolved[current_d] -= 1
            score += (current_d+1)*100
            cnt += 1

        
        else:
            current_d -= 1
            
            if current_d < 0:
                return

    

    
    if cnt < ans:
        ans = cnt


flag = ""
CombiBonus(flag)

print(ans)

Solution (Python):
import math
D,G=map(int,input().split())
PC=[list(map(int,input().split())) for i in range(D)]
zenkan=[]
def saiki(A):
    if len(A)==D:
        ans=0
        count=0
        toita=[]
        for i in range(D):
            if A[i]==1:
                ans+=PC[i][0]*(i+1)*100+PC[i][1]
                count+=PC[i][0]
                toita.append(i)
        zenkan.append([ans,count,toita])
        return ans
    for i in range(2):
        A.append(i)
        saiki(A)
        A.pop()
saiki([])
ans=[]
zenkan.sort()
for i in range(len(zenkan)):
    cost=zenkan[i][1]
    hituyo=G-zenkan[i][0]
    if zenkan[i][0]>=G:
        ans.append(cost)
        continue
    cost_kari=[]
    for j in range(D):
        if j not in zenkan[i][2]:
            if PC[j][0]*100*(j+1)>=hituyo:
                cost_kari.append(math.ceil(hituyo/(100*(j+1))))
            
    cost_kari.sort()
    if len(cost_kari)!=0:
        ans.append(cost+cost_kari[0])
    elif hituyo<=0:
        ans.append(cost)
    


print(min(ans))

Solution (Python):
from math import ceil
from itertools import product


def main():
    d, g = map(int, input().split())
    g //= 100
    p = [0] * d
    c = [0] * d
    r = [0] * d
    for i in range(d):
        _p, _c = map(int, input().split())
        _c //= 100
        p[i] = _p
        c[i] = _c
    ans = sum(p)
    for m in product((0, 1), repeat=d):
        t = 0
        a = 0
        for i in range(d):
            if m[i] == 1:
                t += p[i] * (i + 1) + c[i]
                a += p[i]
        for i in range(d - 1, -1, -1):
            if m[i] == 1:
                continue
            pi = p[i] * (i + 1)
            if t + pi >= g:
                a += ceil(max(g - t, 0) / (i + 1))
                break
            t += pi + c[i]
            a += p[i]
        ans = min(a, ans)
    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
from itertools import product
from math import ceil
def main():
    d, g = map(int, input().split())
    scoremax_set = []
    numq_set = []
    for i1 in range(1, d + 1):
        kazu, bonus = map(int, input().split())
        scoremax_set.append(i1 * 100 * kazu + bonus)
        numq_set.append(kazu)
    score_get_pat = tuple(product((1,0), repeat=d))

    inf = float('inf')
    r = inf

    for sgpe in score_get_pat:
        score = 0
        q_num = 0
        for j1, s in zip(sgpe, scoremax_set):
            score += j1 * s
        for j2, num in zip(sgpe, numq_set):
            q_num += j2 * num
        if score >= g:
            r = min(r, q_num)
        else:
            sgpe_l = [i for i, x in enumerate(sgpe) if x == 0]
            score_plus = (sgpe_l[-1]+1)*100 * (numq_set[sgpe_l[-1]] - 1)
            if score + score_plus >= g:
                q_num += ceil((g - score) / ((sgpe_l[-1]+1)*100))
                r = min(r, q_num)
    print(r)


if __name__ == '__main__':
    main()

Solution (Python):
D, G = map(int, input().split())
p_list = [list(map(int, input().split())) for i in range(D)]



ans = 10**18
from itertools import product

for bit in product((0,1), repeat=D):
    point = 0
    mondai = 0
    
    for i in range(D):
        point += bit[i]*p_list[i][0]*100*(i+1)
        if bit[i] == 1:
            mondai +=p_list[i][0]
            point += p_list[i][1]
    
    if G - point > 0:
        
        a = [i for i, x in enumerate(bit) if x == 0]
        lastbit = int(a[-1])
        for j in range(p_list[lastbit][0]):
            point += (lastbit+1) * 100
            mondai += 1
            if (G - point <= 0):
                ans = min(ans, mondai)
                break
        
        if G - point > 0:
            mondai = 10 ** 18

    ans = min(ans, mondai)

print(ans)

Solution (Python):


import sys
import numpy
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,factorial
from operator import itemgetter
from copy import deepcopy
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 SI(): return input().rstrip()
def printns(x): print('\n'.join(x))
def printni(x): print('\n'.join(list(map(str,x))))
inf = 10**17
mod = 10**9 + 7

d,g=MI()
lis=[LI() for i in range(d)]
answers=[]
for i in product([0,1],repeat=d):
    new_lis=deepcopy(lis)
    point=0
    problems=0
    for j in range(d):
        if i[j]==1:
            point+=lis[j][1]+100*(j+1)*(lis[j][0])
            problems+=lis[j][0]
            new_lis[j][0]=0
        else:
            if new_lis[j][0]>0:
                new_lis[j][0]-=1
    
    flag=True
    for j in range(d):
        k=d-j-1
        if point>=g:
            answers.append(problems)
            flag=False
            break
        else:
            req=(g-point)//(100*(k+1))
            
            if new_lis[k][0]>=req:
                problems+=req
                point+=req*100*(k+1)
            else:
                problems+=new_lis[k][0]
                point+=new_lis[k][0]*100*(k+1)
    if point>=g and flag==True:
        answers.append(problems)

print(min(answers))

Solution (Python):
D, G = map(int, input().split())
pc = [list(map(int, input().split())) for _ in range(D)]

comp = [pc[i][0]*(i+1)*100+pc[i][1] for i in range(D)]

ans = 1000
for bit in range(2**D):
  solved = []
  for j in range(D):
    if 1&(bit>>j):
      solved.append(j)
  now = 0
  ps = 0
  for i in solved:
    now += comp[i]
    ps += pc[i][0]
  if now >= G:
    ans = min(ans, ps)
  else:
    for k in range(D):
      if D-k-1 in solved:
        continue
      if now + (D-k)*100*(pc[k][0]-1) >= G:
        ps += (G-now-100)//((D-k)*100) + 1
        ans = min(ans, ps)
      else:
        break
        
print(ans)

Solution (Python):
d, g = map(int, input().split())
pc = [list(map(int, input().split())) for _ in range(d)]

import math
ans = float('inf')
for i in range(1 << d):
    point = 0
    solved = 0

    for j in range(d):
        if (i >> j) & 1:
            point += pc[j][1] + pc[j][0] * 100 * (j + 1)
            solved += pc[j][0]

    if point >= g:
        f = True
    else:
        f = False
        for j in reversed(range(d)):
            if not ((i >> j) & 1):
                if point + (j + 1) * 100 * (pc[j][0] - 1) >= g:
                    _solved = math.ceil((g - point) / ((j + 1) * 100))
                    solved += _solved
                    point += _solved * 100 * (j + 1)
                    f = True
                    break
                else:
                    _solved = pc[j][0] - 1
                    solved += _solved
                    point += _solved * 100 * (j + 1)

    if f:
        ans = min(ans, solved)

print(ans)

Solution (Python):
d,g = map(int,input().split())
pc = []
for i in range(d):
    p,c = map(int,input().split())
    pc.append([p,c])
ans = 10 ** 18
for bit in range(2**d):
    count = 0
    sump = 0
    se = set()
    for i in range(d):
        if bit >> i & 1:
            sump += pc[i][0]*(i+1)*100 + pc[i][1]
            count += pc[i][0]
        else:
            se.add(i+1)
    if sump >=g:
        ans=min(ans,count)
    else:
        s = max(se)
        tmp = min(pc[s-1][0],((g-sump+100*s-1)//(100*s)))
        count += tmp
        sump+=tmp*s*100
        if sump>=g:
            ans=min(ans,count)
print(ans)

Solution (Python):
d,g=map(int,input().split())
s=[list(map(int,input().split())) for _ in range(d)]
from itertools import product
ans=10000
for b in product([0,1],repeat=d):
  t=0
  sc=0
  mi=0
  for i in range(d):
    if b[i]:
      t+=s[i][0]
      sc+=(s[i][1]+(i+1)*100*s[i][0])
    else:
      mi=i
  z=-(-max(0,g-sc)//((mi+1)*100))
  if z>s[mi][0]-1:
    continue
  ans=min(ans,t+z)
print(ans)

Solution (Python):
D, G = map(int, input().split())
G = int(G / 100)
pc = [list(map(int, input().split())) for _ in range(D)]

N = 10 ** 9
for bit in range(2 ** D):
    S = 0
    c = 0
    A = True
    a = -1
    for i in range(D - 1, -1, -1):
        if bit & (1 << i):
            S += (i + 1) * pc[i][0] + int(pc[i][1] / 100)
            c += pc[i][0]
        elif A:
            a = i
            A = False
    if a != -1:
        for i in range(1, pc[a][0]):
            if S >= G:
                break
            S += a + 1
            c += 1
    if S >= G:
        N = min(N, c)

print(N)

Solution (Python):
d,g=list(map(int,input().split()))
p=[list(map(int,input().split()))for i in range(d)]

ans=float("inf")
for bit in range(1<<d):
    count=0;
    sum=0;
    nokori=set(range(1,d+1))
    for i in range(d):
        if bit&(1<<i):
            sum+=p[i][0]*(i+1)*100+p[i][1]
            count+=p[i][0]
            nokori.discard(i+1)
    if sum>=g:
        ans=min(ans,count)
    else:
        use=max(nokori)
        n=min(p[use-1][0],-(-(g-sum)//(100*use)))
        count+=n
        sum+=n*use*100
        if sum>=g:
            ans=min(ans,count)
print(ans)

Solution (Python):
from itertools import product
D, G = map(int, input().split())
P, C = zip(*[map(int, input().split()) for _ in range(D)])
INF = 10**18
ans = INF
for bit in product((0, 1), repeat=D):
    p = list(P)
    cnt = 0
    score = 0
    for i in range(D):
        if bit[i]:
            score += C[i]
            score += P[i]*100*(i+1)
            cnt += P[i]
            p[i] = 0
 
    if score+sum(p[i]*100*(i+1) for i in range(D)) < G:
        continue
 
    idx = D-1
    while score < G:
        while not p[idx]:
            idx -= 1
        score += 100*(idx+1)
        p[idx] -= 1
        cnt += 1
    if cnt < ans:
        ans = cnt
print(ans)

Solution (Python):
from itertools import product
import math

D, G = map(int, input().split()) 
ipcl = []
for i in range(D):
    p, c = map(int, input().split()) 
    ipcl.append( [i+1, p, c] )

pattern = 2
ite = product(range(pattern),repeat=D)

ans = 10**5
for comb in ite:

    curr_ipcl = ipcl[:]
    curr_sum = 0
    curr_prob = 0
    for i, comp in enumerate(comb):
        if comp:
            pi, p,c = ipcl[i]
            curr_sum += (i+1)*p*100
            curr_sum += c
            curr_prob += p
            curr_ipcl[i] = [pi,0,0]
    
    for ipc in reversed(curr_ipcl):
        i,p,c = ipc
        if curr_sum + p*i*100 <= G:
            curr_sum += p*i*100
            curr_prob += p
        else:
            remain = max(0, G-curr_sum)
            curr_prob += math.ceil( remain/(i*100) )
            break

    ans = min(ans, curr_prob)


print(ans)

Solution (Python):
N, G = map(int, input().split())
bonus = []
problems = []
for _ in range(N):
    PI, CI = map(int, input().split())
    problems.append(PI)
    bonus.append(CI)


def calc_rest_score():
    total = 0
    for i, pi in enumerate(problems):
        if pi:
            score = (i+1) * 100
            total += score * pi + bonus[i]
    return total


def make_plan(total_problem, total_score, flag):
    """
    :param total_score: ここまでの合計スコア
    :param total_problem: ここまでの合計問題数
    :param flag: 最後のスコア調整実施済みフラグ
    :return: 合計問題数
    """
    if total_score >= G:
        return total_problem

    

    rest_score = calc_rest_score()  
    if total_score + rest_score < G:
        
        return 10000

    for i in range(N - 1, -1, -1):
        pi = problems[i]
        si = (i + 1) * 100
        if pi == 0:
            continue
        else:
            
            problems[i] = 0
            pn1 = make_plan(total_problem + pi,
                            total_score + si * pi + bonus[i],
                            flag)
            problems[i] = pi
            

            
            if not flag:
                
                min_pn = 10000  
                for j in range(pi, -1, -1):  
                    plus_score = si * j
                    if j == pi:
                        plus_score += bonus[i]
                    problems[i] = 0
                    pn = make_plan(total_problem+j,
                                   total_score+plus_score,
                                   True if j != 0 else flag)
                    
                    problems[i] = pi
                    if pn < min_pn:
                        min_pn = pn
                pn2 = min_pn
            else:
                pn2 = 10000

            return min(pn1, pn2)
    else:
        
        return 10000


print(make_plan(0, 0, False))

Solution (Python):
from pprint import pprint
def main():
    D,G = map(int, input().split())
    p,c = [0]*D,[0]*D
    for i in range(D):
        p[i],c[i] = map(int, input().split())
    qnum = sum(p)
    
    dp = [[0]*(qnum+1) for _ in range(D+1)]
    dp[0] = [0]*(qnum+1)
    ans = qnum
    for i in range(1,D+1):
        
        for j in range(qnum+1):
            
            for k in range(min(p[i-1]+1, j+1)):
                
                if k<p[i-1]:
                    dp[i][j] = max(dp[i][j], dp[i-1][j-k]+100*i*k)
                else:
                    dp[i][j] = max(dp[i][j], dp[i-1][j-k]+100*i*k+c[i-1])
                if dp[i][j]>=G:
                    ans = min(ans, j)
    pprint(ans)

main()

Solution (Python):


import sys
import math
from bisect import bisect_right as br
from bisect import bisect_left as bl
sys.setrecursionlimit(2147483647)
from heapq import heappush, heappop,heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10**9 + 7
inf = float('inf')
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))

d, g = LI()
pc = [LI() for _ in range(d)]

ans = inf
for i in range(1<<d):
    rest = 1
    rest_count = 0
    score = 0
    count = 0
    for j in range(d):
        p, c = pc[j]
        if (i >> j) & 1:
            score += p * (j + 1) * 100 + c
            count += p
        else:
            if rest < (j + 1) * 100:
                rest = (j + 1) * 100
                rest_count = p
    if score >= g:
        ans = min(ans, count)
    else:
        if math.ceil((g - score) / rest) <= rest_count:
            count += math.ceil((g - score) / rest)
            ans = min(ans, count)
print(ans)

Solution (Python):
from itertools import product
D, G = map(int, input().split())
P, C = zip(*[map(int, input().split()) for _ in range(D)])
INF = 10**18
ans = INF
for bit in product((0, 1), repeat=D):
    p = list(P)
    cnt = 0
    score = 0
    for i in range(D):
        if bit[i]:
            score += C[i]
            score += P[i]*100*(i+1)
            cnt += P[i]
            p[i] = 0

    if score+sum(p[i]*100*(i+1) for i in range(D)) < G:
        continue

    idx = D-1
    while score < G:
        while not p[idx]:
            idx -= 1
        score += 100*(idx+1)
        p[idx] -= 1
        cnt += 1
    if cnt < ans:
        ans = cnt
print(ans)

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 make_primes(N):
  max = int(math.sqrt(N))
  seachList = [i for i in range(2,N+1)]
  primeNum = []
  while seachList[0] <= max:
    primeNum.append(seachList[0])
    tmp = seachList[0]
    seachList = [i for i in seachList if i % tmp != 0]
  primeNum.extend(seachList)
  return primeNum


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




D,G = IL()
L = ILL(D)
L = [((i+1)*100,L[i][0],L[i][1]) for i in range(D)]
import copy
def toku(L_,b):
  score = G
  count = 0
  Lset = copy.deepcopy(L_)
  for i in range(D):
    if (b>>i)&1:
      s,a,t = L_[i]
      score -= s*a+t
      Lset.remove(L_[i])
      count += a
  while score>0:
    if Lset:
      s,a,t = Lset.pop()
      if s*(a-1)>score:
        count += -(-score//s)
        score = 0
      else:
        score -= s*(a-1)
        count += a-1
    else:
      count = INF
      score = 0      
  return count

MIN = INF
for b in range(1<<D):
  MIN = min(MIN,toku(L,b))
  
print(MIN)

Solution (Python):
import sys
import math

readline = sys.stdin.readline
readall = sys.stdin.read
ns = lambda: readline().rstrip()
ni = lambda: int(readline().rstrip())
nm = lambda: map(int, readline().split())
nl = lambda: list(map(int, readline().split()))
prl = lambda x: print(*x ,sep='\n')

d,g = nm()
comp = [nl() for _ in range(d)]
ans = 10**10
check = set([i for i in range(d)])
for i in range(2**d):
    res = 0
    times = 0
    visited = set()
    for j in range(d):
        if (i >> j) & 1:
            res += 100 * (j+1)*comp[j][0] + comp[j][1]
            times += comp[j][0]
            visited.add(j)
    if res < g:
        ma = max(check-visited)
        waru =  100 * (ma+1)
        waru_times = math.ceil((g-res)/waru)
        res += 100*waru_times*waru
        if waru_times > comp[ma][0]-1 or res < g:
            continue
        times += waru_times
        if ans > times:
            ans = times
    elif res >= g:
        if ans > times:
            ans = times
print(ans)

Solution (Python):


def main():
    D, G = map(int, input().split())
    p = [None] * D
    c = [None] * D
    for i in range(D):
        p[i], c[i] = map(int, input().split())
    
    ans = 10**18
    for i in range(2**D):
        tmp = 0
        score = 0
        k = 0
        for j in range(D):
            if (i >> j) & 1:
                score += p[j]*100*(j+1) + c[j]
                tmp += p[j]
            else:
                k = j
        tmp2 = 0
        while score < G and tmp2 < p[k]:
            score += 100 * (k+1)
            tmp2 += 1
        if score >= G:
            ans = min(ans,tmp+tmp2)
            
    print(ans)



if __name__ == "__main__":
    main()

Solution (Python):
from itertools import product

d, g = map(int, input().split())
prob = []
for i in range(1, d + 1):
    p, c = map(int, input().split())
    prob.append((i * 100, p, c))  

ans = 1000000000

for prd in product([0, 1], repeat=d):
    cnt = 0
    allScore = 0
    for j, (score, num, bonus) in zip(prd, prob):
        if j == 1:
            cnt += num
            allScore += score * num + bonus

    if allScore < g:
        for j, (score, num, bonus) in zip(prd, prob):
            if j == 0 and (score * num >= g - allScore):
                rest = (g - allScore) // score
                cnt += rest
                allScore += score * rest
                break

    if allScore >= g:
        ans = min(ans, cnt)

print(ans)

Solution (Python):
d, g = map(int, input().split())
pc = [list(map(int, input().split())) for _ in range(d)]
ans = 1001
for i in range(1<<d): 
    count, score, left = 0, 0, 0
    for j in range(d): 
        if (i >> j) & 1: 
            score += (j+1)*100*pc[j][0] + pc[j][1] 
            count += pc[j][0] 
        else: left = j 
    for j in range(pc[left][0]): 
        if score >= g: break
          
        score += (left+1)*100 
        count += 1
    if score >= g: ans = min(ans, count) 
print(ans)

Solution (Python):
(d, g), *s = [list(map(int, i.split())) for i in open(0)]
s = [[i[0] * -~n * 100 + i[1], i[0]] for n, i in enumerate(s)]
a = 10**3
for b in range(1 << d):
    su = sum(s[i][0] * (b >> i & 1) for i in range(d))
    n = sum(s[i][1] * (b >> i & 1) for i in range(d))
    if su < g:
        m = d-bin(b)[2:].zfill(d).find("0")
        e = (su-g)//(m*100)
        if -e < s[m-1][1]:
            a = min(a,n - e)
    if su >= g:
        a = min(a,n)
print(a)

Solution (Python):
(d, g), *s = [list(map(int, i.split())) for i in open(0)]
def c(i,t,l):
    if i==d:
        if t>=g:
            return sum(l)
        else:
            m=d-l[::-1].index(0)
            e = (t - g) // (m * 100)
            if -e < s[m-1][0]:
                return sum(l)-e
            else:
                return 10**3
    return min(c(i+1,t,l+[0]),c(i+1,t+s[i][0]*-~i*100+s[i][1],l+[s[i][0]]))
print(c(0,0,[]))