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):
D,G = [int(x) for x in input().split()]
pc = [0]*D
for i in range(D):
    pc[i] = [int(x) for x in input().split()]


mincnt = 10**9

for i in range(1 << D):
    score = 0
    cnt = 0
    full = []
    non_full = []

    for j in range(D):
        if((i>>j & 1) == 1):
            full += [[(j+1)*100]+pc[j]]
        else:
            non_full += [[(j+1)*100]+pc[j]]

    non_full.reverse()

    for j in full:
        score += j[0]*j[1]+j[2]
        cnt += j[1]
    if(score < G):
        for j in non_full:
            a = 1
            while(score+j[0]*a < G and a<j[1]):
                a += 1
            score += j[0]*a
            cnt += a
            if(score >= G):
                mincnt=min(cnt,mincnt)
                break
    else:
        mincnt=min(cnt,mincnt)
    
print(mincnt)

Solution (Python):
import itertools

D, G = map(int, input().split())
pc = [list(map(int, input().split())) for i in range(D)]

m = 10**10
for comb in itertools.product(*[[0, 1]]*D):
    score = 0
    solve = 0
    stack = []
    for i in range(D):
        p, c = pc[i]
        if comb[i] == 1:
            solve += p
            score += p*(i + 1)*100 + c
        else:
            for j in range(p - 1):
                stack.append(i + 1)
    while score < G and len(stack) != 0:
        score += stack.pop()*100
        solve += 1
    if score >= G:
        m = min(m, solve)
print(m)

Solution (Python):


import math

d,g = map(int,input().split())
p = [0] * d
c = [0] * d
for i in range(d):
    p[i],c[i] = map(int,input().split())

ans = 1000000000

n = d
arr = [0] * n
for i in range(2 ** n):
    for j in range(n):
        if((1&i>>j) == 1):
            arr[j] = 1
        else:
            arr[j] = 0
    
    score = 0
    question = 0
    for j in range(len(arr)):
        if arr[j] == 1:
            score += (j+1)*100*p[j] + c[j]
            question += p[j]
    if score >= g:
        ans = min(ans,question)
    else:
        for j in range(len(arr)-1,-1,-1):
            if arr[j] == 0:
                if g - score <= (j+1)*100*(p[j]-1):
                    temp = math.ceil((g - score) / ((j+1)*100))
                    question += temp
                    ans = min(ans,question)
                break


print(ans)

Solution (Python):
d, g = map(int, input().split())
p = [0] * d
c = [0] * d
ans = 10000000000000000000000000000
for i in range(d):
    p[i], c[i] = map(int, input().split())

for i in range(2**d):
    sum = 0
    num = 0
    for j in range(d):
        if i & (1 << j):
            sum += c[j]+p[j]*100*(j+1)
            num += p[j]
    if sum >= g:
        ans = min(ans, num)
    else:
        for j in range(d-1, -1, -1):
            if i & (1 << j):
                continue
            for k in range(p[j]):
                if sum >= g:
                    break
                sum += 100*(j+1)
                num += 1
        ans = min(ans, num)
print(ans)

Solution (Python):
from math import ceil
ans = float('inf')
D, G = map(int, input().split())
p = [list(map(int, input().split())) for _ in range(D)]
for i in range(1 << D):
    point = 0
    count = 0
    tmp = 0
    for j in range(D):
        if ((i >> j) & 1) == 0:
            if (100 * j + 100) * p[j][0] + p[j][1]:
                tmp = j
        else:
            point += (100 * j + 100) * p[j][0] + p[j][1]
            count += p[j][0]
    if G - point > 100 * (tmp + 1) * p[tmp][0]:
        continue
    count += max(0, ceil((G - point) / (100 * (tmp + 1))))
    ans = min(ans, count)
print(ans)

Solution (Python):
D,G = list(map(int,input().split()))
PC = [tuple(map(int,input().split())) for i in range(D)]
res = 99999999999
for i in range(1 << D):
  n = 0
  po = 0
  for j in range(D):
    if ((i >> j) & 1)  == 1:
      n = n + PC[j][0]
      po = PC[j][1] + po + (j+1)*100*PC[j][0]
  if po >= G:
    res = min(n,res)
    continue
  for j in reversed(range(D)):
    if ((i >> j) & 1)  == 0:
      if po + (j+1)*100*(PC[j][0] - 1)  >= G:
        n = n + (G-po+100*(j+1)-1)//(100*(j+1))
        po = G+1
        break
      else:
      	n = n + PC[j][0] - 1
      	po = po + (j+1)*100*(PC[j][0] - 1)
  if po >= G:
  	res = min(n,res)

print(res)

Solution (Python):
D, G = map(int, input().split())
p = [None for _ in range(D)]
c = [None for _ in range(D)]
s = [None for _ in range(D)]
for i in range(D):
    p[i], c[i] = map(int, input().split())
    s[i] = 100 * (i + 1) * p[i] + c[i]

INF = 10 ** 9
ans = []
for i in range(2 ** D):
    ii = bin(i)[2:]
    ii = '0' * (D - len(ii)) + ii
    y = 0
    x = 0
    for j in range(D):
        if ii[j] == '1':
            y += s[j]
            x += p[j]
    yy = G - y
    if yy > 0:
        xx = sum(p)
        flag = False
        for j in range(D):
            xt = x
            if ii[j] == '0':
                ss = 100 * (j + 1)
                if (yy + ss - 1) // ss < p[j]:
                    xt += (yy + ss - 1) // ss
                    if xt < xx:
                        xx = xt
                        flag = True
        if flag:
            x = xx
        else:
            x = INF
    ans.append(x)
print(min(ans))

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

ans = 1e9
for i in range(1 << D):
  point = 0
  cnt = 0
  for j in range(D):
    if (i >> j)& 1:
      point += PC[j][0]*(j+1)*100+PC[j][1]
      cnt += PC[j][0]
    else:
      tmp = j
  if point < G:
    R = G-point
    if (PC[tmp][0]-1)*(tmp+1)*100 < R:
      continue
    cnt += -(-R//(100*(tmp+1)))
  ans = min(ans, cnt)
print(ans)

Solution (Python):
d,g = map(int,input().split())
answer = 0
Q = []
for i in range(d):
    p,c=map(int,input().split())
    answer += p
    Q.append((i+1,p,c))

dp = [-10**9]*(answer+1) 
dp[0] = 0
for i,p,c in Q:
    for j in range(answer,-1,-1):
        for k in range(1,p+1):
            cc = i*100*k
            if k == p:
                cc += c
            if j-k >= 0:
                dp[j]=max(dp[j],dp[j-k]+cc)
        
for i in range(answer+1):
    if dp[i] >= g:
        print(i)
        exit()

Solution (Python):
d,g = map(int,input().split())
P = []
C = []
for i in range(d):
    p,c = map(int,input().split())
    P.append(p)
    C.append(c)
    
def f(p,c):
    if p==0:
        return 10**9
    m = min(c//(p*100),P[p-1])
    s = 100*p*m
    if m == P[p-1]:
        s += C[p-1]
    if s < c:
        m += f(p-1,c-s)
    return min(m,f(p-1,c))

print(f(d,g))

Solution (Python):
from bisect import bisect_left, bisect_right
from collections import Counter, defaultdict, deque, OrderedDict
from copy import deepcopy
from functools import lru_cache, reduce
from math import ceil, floor
from sys import setrecursionlimit

import heapq
import itertools
import operator


inf = float('inf')



D, G = 0, 0
P, C = [], []


def set_inputs():
    global D, G, P, C
    D, G = get_li()
    P, C = get_data(D, [int, int])
    return


def main():
    setrecursionlimit(100000)
    set_inputs()
    all_d = set(range(1, D+1))
    ans = inf
    for i in range(2 ** D):
        comp_d = {j + 1 for j in range(D) if ((1 << j) & i) != 0}
        p = sum(100 * d * P[d-1] + C[d-1] for d in comp_d)
        s = sum(P[d-1] for d in comp_d)
        additional_p = 0
        available_p = 0
        if p < G and i != 2 ** D - 1:
            max_other_d = max(all_d - comp_d)
            additional_p = 100 * max_other_d
            available_p = additional_p * (P[max_other_d-1] - 1)
        if p + available_p < G:
            continue
        tmp = s
        if additional_p:
            tmp += (G - p + additional_p - 1) // additional_p
        ans = min(ans, tmp)
    print(ans)
    return


def get_int():
    return int(input())


def get_float():
    return float(input())


def get_str():
    return input().strip()


def get_li():
    return [int(i) for i in input().split()]


def get_lf():
    return [float(f) for f in input().split()]


def get_lc():
    return list(input().strip())


def get_data(n, types):
    if len(types) == 1:
        return [types[0](input()) for _ in range(n)]
    return zip(*(
        [t(x) for t, x in zip(types, input().split())]
        for _ in range(n)
    ))


if __name__ == '__main__':
    main()

Solution (Python):
import itertools
import math
import sys

d, g = [int(x) for x in input()[:-2].split()]
pc = [[int(x) for x in input()[:-2].split()] for _ in range(d)]

def search(choice):
    total = sum(((i + 1) * p + c) * chosen for i, ((p, c), chosen) in enumerate(zip(pc, choice)))
    count = sum(p * chosen for (p, _), chosen in zip(pc, choice))

    if total < g:
        partial = d - list(reversed(choice)).index(0)
        partial_count = math.ceil((g - total) / partial)
        if partial_count <= pc[partial - 1][0]:
            count += partial_count
        else:
            count = sys.maxsize

    return count

print(min(search(choice) for choice in itertools.product(*([0, 1] for _ in range(d)))))

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

l_p=[0 for i in range(d)]
l_c=[0 for i in range(d)]
for i in range(d):
    p,c=map(int,input().split())
    
    l_p[i]=p
    l_c[i]=c







num_q_min=100*d
for i in range(2**d):
    num_q=0
    poi=0
    l_sol=[0]*d
    for j in range(d):
        if i&1:
            num_q+=l_p[j]
            poi+=l_c[j]+100*(j+1)*l_p[j]
            l_sol[j]=1
        i>>=1
    
    
    for j in range(d):
        if poi>=g:
            if num_q<num_q_min:
                num_q_min=num_q
                
            break
        if l_sol[d-1-j]==0:
            delta=(g-poi+100*(d-j)-1)//(100*(d-j))
            if delta>l_p[d-1-j]:
                num_q+=l_p[d-1-j]
                poi+=100*(d-j)*l_p[d-1-j]
            else:
                num_q+=delta
                if num_q<num_q_min:
                    num_q_min=num_q
                    
                break

print(num_q_min)

Solution (Python):
import sys
d,g=map(int,input().split())
l=[[int(i) for i in l.split()] for l in sys.stdin]
def dfs(x,num,cost,flag):
  if x==len(l):
    return 10**18
  num1=num+l[x][0]*100*(x+1)+l[x][1]
  cost1=cost+l[x][0]
  flag1=flag|(2**x)
  cost3=dfs(x+1,num1,cost1,flag1)
  num2=num
  cost2=cost
  flag2=flag
  cost4=dfs(x+1,num2,cost2,flag2)
  for i in range(len(l),0,-1):
    if 2**(i-1)&flag1>0:
      continue
    if num1>=g:
      break
    if (g-num1+i*100-1)//(i*100)<l[i-1][0]:
      cost1+=(g-num1+i*100-1)//(i*100)
      num1+=((g-num1+i*100-1)//(i*100))*100*i
      break
    else:
      num1+=l[i-1][0]*100*i+l[i-1][1]
      cost1+=l[i-1][0]
  for i in range(len(l),0,-1):
    if 2**(i-1)&flag2>0:
      continue
    if num2>=g:
      break
    if (g-num2+(i*100)-1)//(i*100)<l[i-1][0]:
      cost2+=(g-num2+(i*100)-1)//(i*100)
      num2+=((g-num2+(i*100)-1)//(i*100))*100*i
      break
    else:
      num2+=l[i-1][0]*100*i+l[i-1][1]
      cost2+=l[i-1][0]
  if num1<g:
    cost1=10**18
  if num2<g:
    cost2=10**18
  cost=min(cost1,cost2,cost3,cost4)
  return cost
print(dfs(0,0,0,0))

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

p = [[i*100] + [int(_) for _ in input().split()] for i in range(1, D+1)]
p.sort(reverse=True)

def dfs(pos, total, maxpos, count, ans):
    if total >= G:
        if count < ans:
            return count
    if pos >= D:
        if maxpos < D:
            for i in range(1, p[maxpos][1]+1):
                if total + i * p[maxpos][0] >= G:
                    if count + i < ans:
                        return count + i
        return ans

    ans1 = dfs(pos+1, total, maxpos, count, ans)
    ans2 = dfs(pos+1, total+p[pos][0]*p[pos][1]+p[pos][2],
            maxpos+1 if pos==maxpos else maxpos, count+p[pos][1], ans)

    return min(ans, ans1, ans2)

print(dfs(0,0,0,0,10000))

Solution (Python):
D, G = map(int, input().split())
p = [0] * (D)
c = [0] * (D)
for i in range(D):
    p[i], c[i] = map(int, input().split())

ans = 10000

for i in range(1 << D):
    bonus_sum = 0
    cnt = 0
    for j in range(D):
        if (i >> j) & 1 == 1:
            bonus_sum += c[j] + (j + 1) * 100 * p[j]
            cnt += p[j]
    
    if bonus_sum >= G:
        ans = min(ans, cnt)
    
    
    
    else:
        
        for j in range(D)[::-1]:
            if (i >> j) & 1 == 0:
                
                for k in range(p[j]):
                    ten = (j + 1) * 100 * k
                    if ten + bonus_sum < G:
                        continue
                    else:
                        cnt += k
                        ans = min(ans, cnt)
                        break
                
                break

print(ans)

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

def solve(g,i):
    if i<=0:
        return float('inf')
    n = min(int(g/(100*i)),PC[i-1][0])
    score = 100 * i * n
    if n == PC[i-1][0]:
        score += PC[i-1][1]
    if g > score:
        n += solve(g-score,i-1)
    return min(n,solve(g,i-1))

print(solve(g,d))

Solution (Python):


import itertools
import collections
import bisect
import math

def main():
    D, G = map(int, input().split())
    p = []
    c = []
    for _ in range(D):
        pi, ci  = map(int, input().split())
        p.append(pi)
        c.append(ci)


    
    INF = int(1e15)
    ans = INF
    
    pattern = 1 << D  
    for i in range(pattern):
        scope = []
        for j in range(D):
            if (i >> j) & 1:
                scope.append(j)

        score = 0
        result = 0
        for s in scope:
            score += (s + 1) * p[s] * 100 + c[s]
            result += p[s]

        
        if score < G:
            for idx in range(D - 1, -1, -1):
                if idx not in scope:
                    rest = G - score
                    count = min(math.ceil(rest / ((idx + 1) * 100)), p[idx])
                    
                    score += (idx + 1) * count * 100
                    result += count
                    break

        
        if score >= G:
            ans = min(ans, result)

    print(ans)


if __name__ == '__main__':
    main()

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


def solve(G, i):
    if i <= 0:
        return float('inf')
    n = min(int(G/(100*i)), PC[i-1][0])
    score = 100 * i * n
    if n == PC[i-1][0]:
        score += PC[i-1][1]
    if G > score:
        n += solve(G-score, i-1)
    return min(n, solve(G, i-1))


print(solve(G, D))

Solution (Python):
D, G = map(int, input().split())
P, C = [], []

for _ in range(D):
    p, c = map(int, input().split())
    P.append(p); C.append(c)

ans = float('inf')

for bit in range(2**D):
    score, solve_num = 0, 0

    for i in range(D):
        if (bit >> i) & 1:
            score += (100 * (i+1) * P[i] + C[i])
            solve_num += P[i]

    for i in range(D-1, -1, -1):
        if score >= G:
            break

        if (bit >> i) & 1:
            continue

        for j in range(P[i]):
            score += 100*(i+1)
            solve_num += 1

            if score >= G:
                break

    ans = min(ans, solve_num)

print(ans)

Solution (Python):
D, G = map(int, input().split())
P, C = [], []

for _ in range(D):
    p, c = map(int, input().split())
    P.append(p); C.append(c)

ans = float('inf')

for bit in range(2**D):
    is_solve = [ 0 for _ in range(D) ]
    score, solve_num = 0, 0
    
    for i in range(D):
        if (bit >> i) & 1:
            score += (100 * (i+1) * P[i] + C[i])
            solve_num += P[i]
            is_solve[i] += P[i]

    for i in range(D-1, -1, -1):
        if score >= G:
            break

        while is_solve[i] < P[i]:
            score += 100*(i+1)
            solve_num += 1
            is_solve[i] += 1
            if score >= G:
                break

    ans = min(ans, solve_num)

print(ans)

Solution (Python):

import sys

def main():
	D, G = map(int, input().split(" "))
	
	score_board = []
	all_bms = []
	for i in range(D):
		a, b = map(int, input().split(" "))
		score_board.append((a, b))
		all_bms.append(((i+1) * 100 * a) + b)
	
	ans = 1000000000000
	for i in range(2 ** D):
		total = 0
		turn = 0
		p = 0
		for j in range(D):
			if i >> j & 1 == 1:
				total += all_bms[j]
				a, b = score_board[j]
				turn += a
			else:
				p = j
				
		if G <= total and ans > turn:
			ans = turn
			continue
			
		a, b = score_board[p]
		for i in range(a):
			turn += 1
			total = total + (100 * (p+1))
			if G <= total and ans > turn:
				ans = turn
				continue
		total += b
		if G <= total and ans > turn:
			ans = turn
				
			
	print(ans)
		
if __name__ == "__main__":
	main()

Solution (Python):
import math
d, g = map(int, input().split())
questions = [list(map(int, input().split())) for _ in range(d)]
ans = 10**9

for i in range(2**d):
    score = 0
    problems = 0
    resindex = -1  
    for j in range(d):
        
        
        if i >> j & 1 == 1:
            
            score += (j+1)*100*questions[j][0] + questions[j][1]
            problems += questions[j][0]
        else:
            resindex = j
    
    if g <= score:
        ans = min(ans, problems)
    
    
    elif 0 <= resindex \
            and g <= score + questions[resindex][0]*(resindex+1)*100:
        problems += -(-(g-score) // ((resindex+1)*100))
        
        ans = min(ans, problems)

print(ans)

Solution (Python):
from collections import deque

D, G = map(int, input().split())
G //= 100
p = [0]
c = [0]
for _ in range(D):
    pi, ci = map(int, input().split())
    p.append(pi)
    c.append(ci // 100)

q = deque()
q.append((0, 0, 0, " "))
ans = float("inf")
while len(q):
    i, m, g, s = q.pop()
    if i != D:
        q.append((i + 1, m, g, s + "0"))
        q.append((i + 1, m + p[i + 1], g + (i + 1)
                  * p[i + 1] + c[i + 1], s + "1"))
        continue

    if g < G:
        j = s.rfind("0")
        if j < 0:
            continue
        if g + j * (p[j] - 1) < G:
            continue
        m += (G - g + j - 1) // j  

    ans = min(ans, m)

print(ans)

Solution (Python):

from collections import defaultdict
from collections import deque
from heapq import heappush, heappop
import sys
import math
import bisect
import random
import itertools
sys.setrecursionlimit(10**5)
stdin = sys.stdin
def LI(): return list(map(int, stdin.readline().split()))
def LF(): return list(map(float, stdin.readline().split()))
def LI_(): return list(map(lambda x: int(x)-1, stdin.readline().split()))
def II(): return int(stdin.readline())
def IF(): return float(stdin.readline())
def LS(): return list(map(list, stdin.readline().split()))
def S(): return list(stdin.readline().rstrip())
def IR(n): return [II() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def FR(n): return [IF() for _ in range(n)]
def LFR(n): return [LI() for _ in range(n)]
def LIR_(n): return [LI_() for _ in range(n)]
def SR(n): return [S() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
mod = 1000000007


def A():
    return


def B():
    return


def C():
    d, g = LI()
    pc = LIR(d)
    ans = float("INF")
    tokumono = list(itertools.product((0, 1), repeat=d))
    
    for toku in tokumono:
        
        ansa = 0
        ansb = 0
        for i in range(len(toku)):
            if toku[i] == 1:
                ansa += pc[i][0]
                ansb += pc[i][0] * (i + 1) * 100 + pc[i][1]
        for k in range(len(toku) - 1, -1, -1):
            if toku[k] == 0:
                for i in range(pc[k][0] + 1):
                    
                    if i == pc[k][0]:
                        ansb += pc[k][1]
                    if ansb >= g:
                        ans = min(ans, ansa)
                        break
                    ansa += 1
                    ansb += (k+1) * 100
                break

        

    print(ans)
            

    return


def D():
    N, X = LI()
    def dfs(n, x):
        
        if x == 1 and n > 0:
            return 0 
        elif x < 2 ** (n + 1) - 1:
            return dfs(n - 1, x - 1)
        elif x == 2 ** (n + 1) - 1:
            return 2 ** n 
        elif x == 2 ** (n + 2) - 3:
            return 2 ** (n + 1) - 1
        else:
            return dfs(n - 1, x - 2 ** (n + 1) + 1) + 2 ** n 
    a = dfs(N, X)
    print(a)
        
    return



def E():
    return


def F():
    return


def G():
    return


def H():
    return


if __name__ == '__main__':
    C()

Solution (Python):
import itertools as it
D, G = map(int, input().split())
P, C = [], []
for _ in range(D):
    p, c = map(int, input().split())
    P.append(p)
    C.append(c)
A = it.permutations([i for i in range(D)])
ans = 10**9
for a in A:
    S, i, sub_ans = 0, 0, 0
    while 1:
        if S + (a[i] + 1) * 100 * P[a[i]] < G:
            S += (a[i] + 1) * 100 * P[a[i]]
            sub_ans += P[a[i]]
        else:
            x = (G - S) // ((a[i] + 1) * 100)
            if S + (a[i] + 1) * 100 * x < G:
                x += 1
            sub_ans += x
            S += (a[i] + 1) * 100 * x
        S += C[a[i]]
        if S >= G:
            if sub_ans < ans:
                ans = sub_ans
            break
        i += 1
print(ans)

Solution (Python):

from collections import defaultdict
from collections import deque
from heapq import heappush, heappop
import sys
import math
import bisect
import random
def LI(): return list(map(int, sys.stdin.readline().split()))
def I(): return int(sys.stdin.readline())
def LS():return list(map(list, sys.stdin.readline().split()))
def S(): return list(sys.stdin.readline())[:-1]
def IR(n):
    l = [None for i in range(n)]
    for i in range(n):l[i] = I()
    return l
def LIR(n):
    l = [None for i in range(n)]
    for i in range(n):l[i] = LI()
    return l
def SR(n):
    l = [None for i in range(n)]
    for i in range(n):l[i] = S()
    return l
def LSR(n):
    l = [None for i in range(n)]
    for i in range(n):l[i] = SR()
    return l
mod = 1000000007


def A():
    return


def B():
    return


def C():
    def dfs(i,k):
        if i == d:
            l.append(k)
        else:
            for j in range(2):
                dfs(i+1,k+[j])
    d,g = LI()
    p = LIR(d)
    ans = float("inf")
    l = []
    dfs(0,[])
    for k in l:
        m = 0
        o = 0
        q = [[p[i][0],p[i][1]] for i in range(d)]
        for i in range(d):
            if k[i]:
                o += q[i][0]
                m += q[i][0]*(i+1)*100+q[i][1]
                q[i][0] = 0
        while m < g:
            for i in range(d)[::-1]:
                for j in range(q[i][0]):
                    m += (i+1)*100
                    o += 1
                    if m >= g:break
                if m >= g:break
        ans = min(ans,o)
    print(ans)

def D():
    return


def E():
    return


def F():
    return


def G():
    return


def H():
    return


if __name__ == "__main__":
    C()

Solution (Python):
D,target=map(int,input().split())
l=[]
ans=10**9

for i in range(D):
    l.append(list(map(int,input().split())))

for i in range(2**D):
    score=0
    problems=0
    resindex=-1
    for j in range(D):
        if i>>j&1==1:
            score+=(j+1)*100*l[j][0]+l[j][1]
            problems+=l[j][0]
        else:
            resindex=j

    if score>=target:
        ans=min(ans,problems)
    elif resindex>=0 and score+l[resindex][0]*(resindex+1)*100>=target:
        problems+=-(-(target-score)//((resindex+1)*100))
        ans=min(ans,problems)

print(ans)

Solution (Python):
D, G = map(int, input().split())
p = D * [0]
c = D * [0]
for i in range(D):
    p[i], c[i] = map(int, input().split())

counter = []

for i in range(1 << D):
    goukei = 0
    count = 0
    amari = [i for i in range(D)]
    for j in range(D):
        if (i >> j) & 1:
            goukei += p[j] * 100 * (j + 1) + c[j]
            count += p[j]
            amari.remove(j)
    if goukei < G:
        for i in range(p[max(amari)]):
            goukei += 100 * (max(amari) + 1)
            count += 1
            if goukei >= G:
                counter.append(count)
                break
    else:
        counter.append(count)

print(min(counter))

Solution (Python):
D, G = map(int, input().split())
p = [0]*D
c = [0]*D
for d in range(D):
    p[d], c[d] = map(int, input().split())

time_list = []
for i in range(1<<D):
    point = 0
    time = 0
    output = []
    
        
        
            
    
    for d in range(D):
        if ((i>>d) & 1) == 1:
            point += 100*(d+1)* p[d] + c[d]
            time += p[d]
    if point < G:
        
        for d in range(D)[::-1]:
            if ((i>>d) & 1) == 0: 
                for k in range(p[d]):
                    if point < G:
                        point += 100*(d+1) 
                        time += 1
                    else: break
                break
            else: continue
    if point >= G:
        time_list.append(time)
print(min(time_list))

Solution (Python):
import math

D, G = list(map(int, input().split()))
p = [list(map(int, input().split())) for _ in range(D)]
ResMin = 1000

for i in range(2**D):
    numProb = 0
    numPoint = 0
    maxProb = 0
    bonusflag = [0]*D
    for j in range(D):
        if ((i >> j) & 1):
            bonusflag[D-1-j] = 1

    for k in range(D):
        if bonusflag[k] == 1:
            numProb += p[k][0]
            numPoint += (100*(k+1)*p[k][0] + p[k][1])
        else:
            maxProb = k
    if numPoint < G:
        sub = math.ceil((G-numPoint)/(100*(maxProb+1)))
        if sub <= p[maxProb][0]:
            numProb += sub
        else:
            continue
    if numProb < ResMin:
        ResMin = numProb

print(ResMin)

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


cost_list = []
for i in range(1<<D):
    point = 0
    cost = 0
    for j in range(D):
        if ((i>>j) & 1) == 1:
            point += 100* mat[j][1] * mat[j][0] + mat[j][2]
            cost += mat[j][1]
    if point < G:
        
        for j in range(D)[::-1]:
            if ((i>>j) & 1) == 0: 
                for k in range(mat[j][1]):
                    if point < G:
                        point += 100* mat[j][0] 
                        cost += 1
                    else: break
                break
            else: continue
    if point >= G:
        cost_list.append(cost)
print(min(cost_list))

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

p=[]
c=[]

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


def ans(g,t):
    if t<=0:
        return 100000000000
    n=min(int(g/(100*t)),p[t-1])
    s=100*t*n
    
    if n==p[t-1]:
        s=sum[t-1]
    if g>s:
        n+=ans(g-s,t-1)
    
    return min(n,ans(g,t-1))

print(ans(g,d))

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

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

ans = 10**10
for i in range(1<<(d+1)):
    cnt = 0
    res = 0
    tank = []
    for j in range(d):
        if (i>>j)&1 == 1:
            cnt += s[j]
            res += p[j]
        else:
            tank.append([100*(j+1),p[j]])
    if cnt >= g:
        ans = min(ans,res)
    else:
        while cnt < g and tank[-1][1] > 0:
            cnt += tank[-1][0]
            tank[-1][1] -= 1
            res += 1
        if cnt >= g:
            ans = min(ans,res)
print(ans)

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


MAX_BIT = (1 << D)
minimum = 1000000000

for patternBit in range(MAX_BIT):
    if patternBit >= MAX_BIT:
        continue
    p = patternBit
    score = 0
    ans1 = 0
    use_c = None
    for i, c in enumerate(Ci):
        s = (i + 1) * 100 
        if p % 2 > 0:
            score += s * c[0] + c[1]
            ans1 += c[0]
        else:
            use_c = c + [s]
        p = p // 2
    if score < G:
        remain = G - score
        add_count = remain // use_c[2]
        if remain % use_c[2] > 0:
            add_count += 1
        if add_count > use_c[0]:
            continue
        ans1 += add_count
    minimum = min(minimum, ans1)
    
print(minimum)

Solution (Python):
D,G =(int(i) for i in input().split())
pc = [[int(j) for j in input().split()] for i in range(D)]
unuse = -1
point = total = 0
G /= 100
answer = 1000
for i in range(1 << len(pc)):
  point = 0
  total = 0
  unuse = -1
  for j in range(len(pc)):
    if ((i >> j) & 1) == 1:
      point += pc[j][0] * (j+1) + (pc[j][1] / 100)
      total += pc[j][0]
    else:
      unuse = max(unuse,j)
    if(point >= G):
      answer = min(answer,total)
    elif(unuse > -1 and point + (pc[unuse][0] - 1) * (unuse + 1) >= G):
      if((G - point) % (unuse + 1) == 0):
        answer = min(answer, total+int((G - point) // (unuse + 1)))
      else:
        answer = min(answer, total+int((G - point) // (unuse + 1))+1)     
print(answer)