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 = map(int, input().split())
P = []
C = []
ans = 10 ** 9
for i in range(D):
    p, c = map(int, input().split())
    P.append(p)
    C.append(c)

for i in range(2 ** D):
    a = 0
    b = 0
    for j in range(D):
        if (i >> j) & 1 :
            a += 100 * P[j] * (j + 1) + C[j]
            b += P[j]
    for k in range(D - 1, -1, -1):
        if (i >> k) & 1:
            continue
        if a >= G:
            break
        for l in range(P[k] + 1):
            a += 100 * (k + 1)
            b += 1
            if a >= G:
                break
    ans = min(ans, b)
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**7
for i in range(2**D):
    tmp = 0
    cnt = 0
    rest = list(range(1, D+1))
    for j in range(D):
        if (i >> j) & 1 == 1:
            tmp += pc[j][0] * 100 * (j+1) + pc[j][1]
            cnt += pc[j][0]
            rest.remove(j+1)
    
    if tmp < G:
        plus = max(rest)
        n = min(pc[plus-1][0], -(-(G-tmp) // (plus * 100)))
        cnt += n
        tmp += n * plus * 100
    if tmp >= G:
        ans = min(ans, cnt)
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 = []
for i in range(2**D):
    cnt = 0
    tmp = 0
    nokori = set(range(1, D+1))
    for j in range(D):
        if (i >> j) & 1 == 1:
            tmp += pc[j][0] * (100 * (j+1)) + pc[j][1]
            cnt += pc[j][0]
            nokori.discard(j+1)
    if tmp < G:
        use = max(nokori)
        n = min(pc[use-1][0], -(-(G-tmp) // (use * 100)))
        cnt += n
        tmp += n * use * 100
    
    if tmp >= G:
        ans.append(cnt)

print(min(ans))

Solution (Python):
def main():

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

    hs = [[0, 0, 0]]
    for i, p, c in A:
        temp = []
        for h, v, q in hs: temp.append([h|(1 << i), v+100*(i+1)*p+c, q+p])
        hs += temp

    

    ans = float('inf')
    for h, v, q in hs:
        if v >= G:
            ans = min(ans, q)
        else:
            for i, p, c in A:
                if (h >> i) % 2 == 0:
                    if v + 100*(i+1)*(p-1) < G:
                        v += 100*(i+1)*(p-1)
                        q += p-1
                    else:
                        if (G-v) % (100*(i+1)) == 0:
                            ans = min(ans, q + (G-v) // (100*(i+1)))
                        else:
                            ans = min(ans, q + 1 + (G-v) // (100*(i+1)))
                        break
    return ans

if __name__ == '__main__':
    print(main())

Solution (Python):
def main():

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

    cur = [[0, 0]]
    used = [set()]

    for i, p, c in A:
        temp = []
        temp_used = []
        for j in range(len(cur)):
            temp.append(cur[j])
            temp_used.append(used[j])
            temp.append([cur[j][0]+ 100*(i+1)*p+c, cur[j][1] + p])
            temp_used.append(used[j] | {i})
        cur = temp
        used = temp_used
    
    
    

    ans = float('inf')
    for j in range(len(cur)):
        if cur[j][0] >= G:
            ans = min(ans, cur[j][1])
        else:
            for i, p, c in A:
                if i not in used[j]:
                    if cur[j][0] + 100 * (i+1) * (p-1) < G:
                        cur[j][0] += 100 * (i+1) * (p-1)
                        cur[j][1] += p-1
                    else:
                        if (G - cur[j][0]) % (100*(i+1)) == 0:
                            ans = min(ans, cur[j][1] + (G - cur[j][0]) // (100*(i+1)))
                        else:
                            ans = min(ans, cur[j][1] + (G - cur[j][0]) // (100*(i+1)) + 1)
                        break
    return ans



if __name__ == '__main__':
    print(main())

Solution (Python):
import sys
if sys.platform =='ios':
	sys.stdin=open('Untitled.txt')
input = sys.stdin.readline

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


N = len(pd)

p_effort = []
for i in range(len(pd)):
	p_effort.append([pd[i][0], pd[i][0]*(i+1)*100+pd[i][1]])


bonus_pattern = []
for i in range(2**N):
	bonus = [0] * N
	for j in range(N):
		if (i>>j & 1):
			bonus[N-j-1] = 1
	bonus_pattern.append(bonus)


ans = []
for bp in bonus_pattern:
	total,effort = 0,0
	for i in range(len(bp)):
		if bp[i] == 1:
			total += p_effort[i][1]
			effort += p_effort[i][0]
	
	if total < G:
		for j in range(len(bp)-1,-1,-1):
			if bp[j] == 0:
				for _ in range(pd[j][0]):
					
					total += (j+1)*100
					effort += 1
					if total >= G:
						break
				break
	ans.append([bp,total,effort])


min_effort = float('INF')
for answer in ans:
	if answer[1]>=G:
		min_effort=min(min_effort, answer[2])

print(min_effort)

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)

ans=100000

for i in range(2**D):
    ten=0
    mondaisu=0
    for j in range(D):
        if ((i>>j)&1):
            ten+=(j+1)*100*p[j]+c[j]
            mondaisu+=p[j]
        else:
            k=j
    if ten>=G:
        if ans>mondaisu:
            ans=mondaisu
    else:
        if G-ten<=(k+1)*100*p[k]:
            mondaisu+=(G-ten-1)//((k+1)*100)+1
            if ans>mondaisu:
                ans=mondaisu
print(ans)

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)

ans=100000

for i in range(2**D):
    ten=0
    mondaisu=0
    for j in range(D):
        if ((i>>j)&1):
            ten+=(j+1)*100*p[j]+c[j]
            mondaisu+=p[j]
        else:
            k=j
    if ten>G:
        if ans>mondaisu:
            ans=mondaisu
    else:
        if G-ten<=(k+1)*100*p[k]:
            mondaisu+=(G-ten-1)//((k+1)*100)+1
            if ans>mondaisu:
                ans=mondaisu
print(ans)

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


import itertools
import math
cand = 100000000000000
for pat in itertools.product([0, 1], repeat=d):
  bonus_point = sum([a * p for a, p in zip(All, pat)])
  bonus_n = sum([num * p for num, p in zip(P, pat)])
  total_n = 0

  if bonus_point >= g:
    total_n = bonus_n
  else:
    total_n = bonus_n
    rest = g - bonus_point
    for i in range(d, 0, -1):
      if pat[i-1] == 0:
        if (P[i-1] - 1) * i * 100 >= rest:
          total_n += math.ceil(rest / (i * 100))
          break
        else:
          rest -= (P[i-1] - 1) * i * 100
          total_n += P[i-1]

  cand = min(cand, total_n)
print(cand)

Solution (Python):
import math
d, g = map(int, input().split())
p = []
c = []
su = []
ans = 1000
for i in range(d):
  a,b = map(int, input().split())
  p.append(a)
  c.append(b)
  su.append(a*100*(i+1)+b)
bit = [1,2,4,8,16,32,64,128,256,512]
for i in range(int(math.pow(2,d))):
  count = 0
  score = 0
  for j in range(d):
    if i & bit[j] == 0:
      continue
    score += su[j]
    count += p[j]
  if score < g:
    continue
  for j in range(d):
    if i & bit[j] == 0 or score - su[j] >= g:
      continue
    rest = g - (score - su[j])
    count_tmp = min(count , count - p[j] + math.ceil(rest / ((j+1)*100)))
    ans = min(ans, count_tmp)
print(ans)

Solution (Python):



import math
inf = 10000000000000000
D, G = map(int, input().split())
pc = [list(map(int, input().split())) for _ in range(D)]
ans_cnt = inf


for i in range(2 ** D):
    flag = True
    tmp_score = 0           
    tmp_cnt = 0             
    for j in range(D):      
        if (i >> j) & 1:    
            tmp_score += pc[j][0] * (100 * (j+1)) + pc[j][1]    
            tmp_cnt += pc[j][0]                                 
    if tmp_score < G:       
        for j in range(D-1, -1, -1):    
            if not (i >> j) & 1:
                tmp_tmp_cnt = math.ceil((G - tmp_score) / ((j+1) * 100))        
                if tmp_tmp_cnt > pc[j][0]:          
                    flag = False
                    break
                else:                               
                    tmp_cnt += tmp_tmp_cnt
                    break
    if flag:
        ans_cnt = min(tmp_cnt, ans_cnt)
print(ans_cnt)

Solution (Python):
d,g=map(int,input().split())
l=[]
for i in range(d):
    l.append(list(map(int,input().split())))
op=[[0],[1]]
for i in range(d-1):
    tmp=[]
    for j in op:
        tmp.append(j+[0])
        tmp.append(j+[1])
    op=tmp
ans=10**10
for i in op:
    z=0
    k=[]
    c=0
    for j in range(d):
        if i[j]==1:
            z+=l[j][0]*100*(j+1)+l[j][1]
            c+=l[j][0]
        else:
            k.append(j)
    if z>=g:
        ans=min(ans,c)
    else:
        if len(k)>0:
            m=max(k)
            p=g-z
            cn=-(-p//((m+1)*100))
            if cn<l[m][0]:
                ans=min(ans,c+cn)
print(ans)

Solution (Python):



d, g = map(int, input().split())
pc = [list(map(int, input().split())) for _ 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>>i)&1 == 1 :
            sum += pc[i][0] * (100*(i+1)) + pc[i][1]
            count += pc[i][0]
            
            
            nokori.discard(i+1)

    
    
    
    if sum < g:
        
        use = max(nokori)
        
        
        n = min(pc[use-1][0], -(-(g-sum)//(use*100)))
        count += n
        sum += n * use * 100
    
    if sum >= g:
        ans = min(ans, count)

print(ans)

Solution (Python):



d, g = map(int, input().split())
pc = [list(map(int, input().split())) for _ 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 += pc[i][0] * (100*(i+1)) + pc[i][1]
            count += pc[i][0]
            
            
            nokori.discard(i+1)

    
    
    
    if sum < g:
        
        use = max(nokori)
        
        
        n = min(pc[use-1][0], -(-(g-sum)//(use*100)))
        count += n
        sum += n * use * 100
    
    if sum >= g:
        ans = min(ans, count)

print(ans)

Solution (Python):



def ri():
    return int(input())

def rl():
    return list(input().split())

def rli():
    return list(map(int, input().split()))

def calc(d, mask, probs, g):
    score = 0
    ret = 0
    flags = [mask & (1<<i) for i in range(d)]
    for i in range(d):
        val = (i+1)*100
        p = probs[i][0]
        c = probs[i][1]
        if flags[i]:
            ret += p
            score += c+p*val
    if g <= score:
        return ret
    for i in range(d, -1, -1):
        val = i*100
        p = probs[i-1][0]
        c = probs[i-1][1]
        if flags[i-1]:
            continue
        else:
            if (g - score) > val*(p-1):
                score += val*(p-1)
                ret += p-1
            else:
                np = (g-score+val-1)//val
                score += val*np
                ret += np
                break
    if score < g:
        return 100000
    return ret

def main():
    d, g = rli()
    probs = []
    for i in range(d):
        p, c = rli()
        probs.append([p, c])
    ans = -1
    for i in range(2**d):
        ret = calc(d, i, probs, g)
        
        if ans == -1:
            ans = ret
        else:
            ans = min(ans, ret)
    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
d,g=map(int,input().split())
LC=[]
LB=[]
for i in range(d):
	c,b=map(int,input().split())
	LC.append(c)
	LB.append(b)
ans=sum(LC)
for i in range(1<<d):
	P=0
	c=0
	n=-1
	for j in range(d):
		if i&(1<<j):
			P+=(j+1)*100*LC[j]+LB[j]
			c+=LC[j]
		else:
			n=max(n,j)
	if P>=g:
		ans=min(ans,c)
	else:
		if n!=-1:
			for k in range(LC[n]-1):
				P+=(n+1)*100
				c+=1
				if P>=g:
					ans=min(ans,c)
print(ans)

Solution (Python):
d,g=map(int,input().split())
pl=[]
cl=[]
for i in range(d):
  p,c=map(int,input().split())
  pl.append(p)
  cl.append(c)
bitlist=[]
for i in range(2**d):
  sub=[]
  num=i
  while num!=0:
    sub.append(num%2)
    num=num//2
  while len(sub)<d:
    sub.append(0)
  bitlist.append(sub)
ans=10000
for i in bitlist:
  l=i
  score=0
  count=0
  for i in range(d):
    if l[i]==1:
      score+=pl[i]*(i+1)*100
      score+=cl[i]
      count+=pl[i]
  if score>g:
    if count<ans:
      ans=count
  else:
    b=False
    for j in range(1,d+1):
      if not b:
        if l[-j]==1:
          pass
        else:
          m=min(pl[-j],(g-score)//((d-j+1)*100))
          score+=m*(d-j+1)*100
          count+=m
          if m==pl[-j]:
            score+=cl[-j]
          if score>g:
            b=True
    if count<ans:
      ans=count    
print(ans)

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

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

ans = 1000
for pat in product(["1", "0"], repeat=d):
    score = 0
    cnt = 0
    not_complete = 0
    for i, bl in enumerate(pat):
        if bl == "1":
            score += 100 * (i + 1) * pc[i][0] + pc[i][1]
            cnt += pc[i][0]
        else:
            not_complete = i

    if score < g:
        add = ceil((g - score) / (100 * (not_complete + 1)))
        if add < pc[not_complete][0]:
            cnt += add
        else:
            continue

    ans = min(ans, cnt)

print(ans)

Solution (Python):




D,G = map(int,input().split())
PC = [tuple(map(int,input().split())) for i in range(D)]
ans = 10**3+19
for i in range(2**D):
    score = 0
    solved = 0
    ps = [PC[j][0] for j in range(D)]
    s = bin(i)[::-1][:-2] 
    for j in range(len(s)):
        if s[j] == '1':
            score += PC[j][1]
            score += PC[j][0]*100*(j+1)
            solved += ps[j]
            ps[j] = 0
    i = -1
    while G > score:
        if i < -D:
            solved = 10**3+19
            break
        if ps[i] == 0:
            i -= 1
        else:
            ps[i] -= 1
            score += (D+i+1)*100
            solved += 1
    ans = min(ans,solved)
print(ans)

Solution (Python):
import math


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

point = 0
ans = []

def dfs(i, count, point):
    
    c_ = count
    if point >= G:
        ans.append(count)
        return
    
    if point + (i + 1) * 100 * (pc[i][0] - 1) >= G:
        count += math.ceil((G - point) / ((i + 1) * 100))
        ans.append(count)
    
    elif point + (i + 1) * 100 * pc[i][0] + pc[i][1] >= G:
        count += pc[i][0]
        ans.append(count)
    if i == 0:
        return
    
    dfs(i-1, c_+pc[i][0], point + (i+1)*100 * pc[i][0] + pc[i][1])
    
    dfs(i-1, c_, point)

dfs(D-1,0,0)


print(min(ans))

Solution (Python):
D, G = map(int, input().split())

G = G//100

problems = []

for i in range(D):
    p, c = map(int, input().split())
    problems.append((p, c//100))

ans = 10000

for i in range(1 << D):
    score = 0
    num = 0
    for j in range(D):
        comp = 1 << j
        if i & comp:
            score += (j+1) * problems[j][0] + problems[j][1]
            num += problems[j][0]
    if score < G:
        for k in range(D-1, -1, -1):
            comp = 1 << k
            if not i & comp:
                for l in range(problems[k][0]-1):
                    score += k + 1
                    num += 1
                    if score >= G:
                        break
                else:
                    continue
                break
    if score >= G and ans > num:
        ans = num

print(ans)

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)

anslist = []
def dfs(i, total, count, nokori):
    


    if G <= total:
        anslist.append(count)
        
        return
    if i == D:
        if G > total:
            if len(nokori) == 0:
                return
            for c in sorted(list(nokori), reverse=True):
                for _ in range(P[c]):
                    total += 100*(c+1)
                    count += 1
                    if G <= total:
                        anslist.append(count)
                        
                        return
                
        return
    dfs(i+1, total, count, nokori)
    dfs(i+1, total + 100*(i+1)*P[i]+C[i], count + P[i], nokori - {i})

dfs(0, 0, 0, set(range(D)))
print(min(anslist))

Solution (Python):
import math
D, G = [int(x) for x in input().split()]
PC = [[int(x) for x in input().split()] for _ in range(D)]
ans = 100100
for i in range(2**D):
    cnt = 0
    point = 0
    for j in range(D):
        if (i >> j) & 1:
            cnt += PC[j][0]
            point += 100 * (j+1) * PC[j][0] + PC[j][1]
    if (point < G):
        rest = G-point
        for j in range(D)[::-1]:
            if (i >> j) & 1 == 0:
                if (rest < 100*(j+1)*PC[j][0]):
                    
                    cnt += math.ceil(rest / (100*(j+1)))
                    break 
                else:
                    cnt = 100100
                    break
    ans = min(ans, cnt)
print(ans)

Solution (Python):
D, G = [int(x) for x in input().split()]
PC = [[int(x) for x in input().split()] for _ in range(D)]
ans = 100100
for i in range(2**D):
    cnt = 0
    point = 0
    for j in range(D):
        if (i >> j) & 1:
            cnt += PC[j][0]
            point += 100 * (j+1) * PC[j][0] + PC[j][1]
    if (point < G):
        rest = G-point
        for j in range(D)[::-1]:
            if (i >> j) & 1 == 0:
                if (rest < 100*(j+1)*PC[j][0]):
                    
                    cnt += -(-rest // (100*(j+1)))
                    break 
                else:
                    cnt = 100100
                    break
    ans = min(ans, cnt)
print(ans)

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

counts = []
def calc(i, count, total, last):
  if G <= total:
    counts.append(count)
    return
  if i >= D:
    for x in range(PnC[last][0]):
      if G <= total + 100*x*(last+1):
        counts.append(count + x)
        return
    return
  calc(i+1, count, total, i)
  calc(i+1, count+PnC[i][0], total+PnC[i][1]+100*(i+1)*PnC[i][0], last)

calc(0, 0, 0, 0)
print(min(counts))

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

v=g//100+1
for i in range(2**d):
  c=m=s=0
  for j in range(d):
    if i & 2**j > 0:
      s += p[j][0]*(j+1)*100+p[j][1]
      c += p[j][0]
    else:
      m = j
    if s >= g:
      v=min(v,c)
    elif s+(p[m][0]-1)*(m+1)*100 >=g:
      v=min(v,c+(g-s+100*(m+1)-1)//(100*(m+1)))
print(v)

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

D, G = [int(x) for x in input().strip().split()]
P = [''] * D
for d in range(D):
    p, c = [int(x) for x in input().strip().split()]
    P[d] = [0] + [(d + 1) * 100 * (i + 1) for i in range(p)]
    P[d][-1] += c

d = defaultdict(int)
def f(P, D, qnum, trial, d, flag=False, score=[]):
    if (qnum, trial, sum(score)) in d:
        return d[(qnum, trial, sum(score))]
    
    if qnum == D:
        if sum(score) >= G:
            
            return trial
        else:
            
            return 10 ** 9 + 7
    ret = 10 ** 9 + 7
    if flag:
        N = [0, len(P[qnum])-1]
    else:
        N = range(len(P[qnum]))
    for n in N:
        flag2 = flag
        t = score[:]
        t.append(P[qnum][n])
        if not flag and n != len(P[qnum]) - 1 and n != 0:
            flag2 = True
        ret = min(ret, f(P, D, qnum+1, trial+n, d, flag2, t))
    d[(qnum, trial, sum(score))] = ret
    return ret

print(f(P, D, 0, 0, d))

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())
import numpy as np
import math
b = 2**d
pnum = np.array(p)
cnum = np.array(c)
ans = 10**30
score_comp = np.zeros(d)
for di in range(d):
    score_comp[di] = pnum[di]*(100*(di+1))+cnum[di]

for i in range(b):
    comp_str = bin(i)[2:].zfill(len(bin(b-1))-2)
    comp_num = np.array([float(j) for j in list(comp_str)])
    comp_cnt = int((comp_num*pnum).sum())
    total_comp_score = (comp_num*score_comp).sum()
    if total_comp_score >= g:
        if ans > comp_cnt:
            ans = comp_cnt
    else:
        rest = g-total_comp_score
        rest_id = comp_str.rfind('0')
        if rest_id>=0:
            rest_cnt = math.ceil(rest/(rest_id+1)/100)
            if pnum[rest_id] > rest_cnt:
                if (ans > comp_cnt + rest_cnt):
                    ans = comp_cnt + rest_cnt
print(ans)

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

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

def AccuracyQestionNum(acc_list, count):
    counter = count
    for i in range(len(acc_list)):
        if acc_list[i] == 1:
            counter += p[i]
    return counter

def MaxScoreIndex(acc_list):
    for i in reversed(range(len(acc_list))):
        if acc_list[i] == 0:
            return i
        
def FinalQestionNum(acc_list, score):
    remain_point = G - score
    counter = 0
    max_score_index = MaxScoreIndex(acc_list)
    for i in range(p[max_score_index]):
        remain_point -= (max_score_index+1) * 100
        counter += 1
        if remain_point <= 0:
            break

    if counter == p[max_score_index]:
        return None
    else:
        return counter
        
def ScoreCalculation(acc_list):
    score = 0
    for i in range(len(acc_list)):
        if acc_list[i] == 1:
            score += (i+1) * 100 * p[i]
            score += c[i]
    return score

def DFSQestion(acc_list):
    """先に全探索で得たスコアを計算して, 正解数もカウントしておく"""
    if len(acc_list) == D:
        score = ScoreCalculation(acc_list)
        if score >= G:
            question_num = AccuracyQestionNum(acc_list, 0)
        else:
            count = FinalQestionNum(acc_list, score)
            if count == None:
                return None
            else:
                question_num = AccuracyQestionNum(acc_list, count)
        return question_num
    else:
        question_num1 = DFSQestion(acc_list + [0])
        question_num2 = DFSQestion(acc_list + [1])
        if question_num1 == None:
            return question_num2
        if question_num2 == None:
            return question_num1
        if question_num1 >= question_num2:
            return question_num2
        else:
            return question_num1
        
question_num = DFSQestion([])

print(question_num)



"""
全ての問題に対する全探索(おバカな探索)
sum_question  = 0
for i in range(D):
    sum_question += p[i]

def ScoreCalculation(question_list):
    pre_i = 0
    count = 0
    score = 0
    for p_i in range(len(p)):
        count = sum(question_list[pre_i : pre_i + p[p_i]])
        pre_i += p[p_i]
        score += (p_i+1) * 100 * count
        if count == p[p_i]:
            score += c[p_i]
        
    return score

def DFSAccuracy(question_list):
    if len(question_list) == sum_question:
        score = ScoreCalculation(question_list)
        if score >= G:
            return question_list
        else:
            return None
    else:
        result1 = DFSAccuracy(question_list + [1])
        result2 = DFSAccuracy(question_list + [0])

        if result1 == None:
            return result2
        elif result2 == None:
            return result1
        else:
            que_num1 = sum(result1)
            que_num2 = sum(result2)
            if  que_num1< que_num2:
                return result1
            else:
                return result2

ans_list = DFSAccuracy([])
accuracy_num = sum(ans_list)
print(accuracy_num)
"""

Solution (Python):
n,g = map(int, input().split())
standard = []
bonus = []
num_of_problems = []
for i in range(n):
    a,b = map(int, input().split())
    standard.append(a * (i+1) * 100)
    bonus.append(b)
    num_of_problems.append(a)
points_after_completion = []
min_num = 10 * 100
for i in range(2**n):
    point = 0
    num = 0
    li = list(range(n))
    for j in range(n):
        if (i >> j) & 1:
            point += standard[n-j-1] + bonus[n-j-1]
            num += num_of_problems[n-j-1]
            li.remove(n-j-1)
    counter = 0
    if li != []:
        while point < g and counter <= num_of_problems[li[-1]]:
            point += 100 * (li[-1]+1)
            num += 1
            counter += 1
    if num < min_num and point >= g:
        min_num = num
print(min_num)

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())
s = sum(P)


dp = [[0 for i in range(s+1)] for j in range(D+1)]
for i in range(D):
    p = P[i]
    c = C[i]
    t = 100*(i+1)
    for j in range(s+1):
        for k in range(p+1):
            if k == p:
                if j >= k:
                    dp[i+1][j] = max(dp[i+1][j],dp[i][j-k]+c+t*k)
            else:
                if j >= k:
                    dp[i+1][j] = max(dp[i][j-k]+t*k,dp[i+1][j])
                else:
                    break
for i in range(s+1):
    if dp[D][i] >= G:
        ans = i
        break
print(ans)

Solution (Python):
import sys
sys.setrecursionlimit(2147483647)
INF=float("inf")
MOD=10**9+7
input=lambda :sys.stdin.readline().rstrip()
def resolve():
    from math import ceil
    d,g=map(int,input().split())
    g//=100
    P=[0]*d
    C=[0]*d
    for i in range(d):
        p,c=map(int,input().split())
        c//=100
        P[i],C[i]=p,c

    def check(S):
        comp=[0]*d
        for i in range(d):
            comp[i]=S&1
            S>>=1
        score=0
        cnt=0
        for i in range(d):
            if(comp[i]):
                score+=(i+1)*P[i]+C[i]
                cnt+=P[i]

        
        if(score>=g):
            return cnt

        
        idx=-1
        for i in range(d-1,-1,-1):
            if(comp[i]==0):
                idx=i
                break

        if(idx==-1):
            return False


        k=ceil((g-score)/(idx+1))
        if(k<P[idx]):
            return cnt+k
        else:
            return False


    
    ans=INF
    for S in range(2**d):
        score=check(S)
        if(score): ans=min(score,ans)
    print(ans)
resolve()

Solution (Python):

import math
d,g=map(int,input().split())
lists=[tuple(map(int,input().split())) for i in range(d)]
A=[]
for _ in range(2**d):
    lis=[]
    G=0
    G+=g
    counter=0
    strings=format(_,"0%ib"%d)
    strings=strings[::-1]
    for i in range(d):
        if strings[i]=="1":
            G-=(lists[i][0]*100*(i+1)+lists[i][1])
            counter+=lists[i][0]
        else:
            lis.append((lists[i][0],(i+1)*100))
    if G<=0:
        A.append(counter)
    else:
        lis=sorted(lis,key=lambda x:x[1],reverse=True)
        lis.append("END")
        
        flag=True
        for some in lis:
            if not(G>0 and flag):
                break            
            if some=="END":
                flag=False
            else:
                limit=some[0]-1
                number=some[1]
                if G>limit*number:
                    G=G-number*limit
                    counter+=limit
                else:
                    P=math.ceil(G/number)
                    counter=counter+P
                    A.append(counter)
                    flag=False

        if G<=0:
            A.append(counter)

print(min(A) )

Solution (Python):
D,G=map(int,input().split())
p=[0];c=[0]
for i in range(1,D+1):
    pi,ci=map(int,input().split())
    p.append(pi);c.append(ci)

ans=sum(p)
for k in range(1<<D):
    s=[i for i in range(1,D+1) if k>>(i-1)&1]
    t=sorted([j for j in range(1,D+1) if j not in s],reverse=True)

    ac=sum([p[i] for i in s])
    score=sum([100*i*p[i]+c[i] for i in s])

    for j in t:
        if score>=G:
            break
        q=(G-score+(j-1)*100)//(j*100)
        if q>=p[j]:
            ac+=p[j]-1
            score+=(j*100)*(p[j]-1)
        else:
            ac+=q
            score+=(j*100)*q
    if score>=G:
        ans=min(ans,ac)

print(ans)