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 = []
PC = [list(map(int, input().split())) for _ in range(D)]
PC = [0] + PC


def dfs(G, i):
    if i == 0:
        return 10**12
    n = min((G-1)//(100*i)+1, PC[i][0])
    
    tmp = n*100*i
    if n == PC[i][0]:
        tmp += PC[i][1]
    if tmp < G:
        n += dfs(G-tmp, i-1)
    return min(n, dfs(G, i-1))

print(dfs(G, D))

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)
ans = float("inf")
for bit in range(1 << D) :
    AC = 0
    SCORE = 0
    for k in range(D) :
        if bit & (1 << k) :
            AC += P[k]
            SCORE += (k+1)*100*P[k]+C[k]
    if SCORE >= G :
        ans = min(ans,AC)
    else :
        for k in range(D-1,-1,-1) :
            if bit & (1 << k) :
                continue
            rest = G - SCORE
            if rest > (k+1)*100*P[k]+C[k] :
                AC += P[k]
                SCORE += (k+1)*100*P[k]+C[k]
            else :
                AC += rest//((k+1)*100)
                if rest % ((k+1)*100) :
                    AC += 1
                ans = min(ans,AC)
                break
print(ans)

Solution (Python):
ranknum,goal = map(int,input().split())
probnum = [0]*ranknum
bonus = [0]*ranknum
compscore = [0]*ranknum

for i in range(ranknum):
    probnum[i],bonus[i] = map(int,input().split())
    compscore[i] = probnum[i]*100*(i+1)+bonus[i]

from itertools import product
from math import ceil

minprob = 1001

for c in product(range(2),repeat=ranknum):
    score = 0
    solvedprob = 0
    notcompedindex = -1

    for i in range(ranknum):    
        if c[i] == 1:
            score += compscore[i]
            solvedprob += probnum[i]
        else:
            notcompedindex = i
        
    if score < goal and score+100*(notcompedindex+1)*(probnum[notcompedindex]-1) >= goal:
        solvedprob += ceil((goal-score)/(100*(notcompedindex+1)))
        score += ceil((goal-score)/(100*(notcompedindex+1))) * (100*(notcompedindex+1))
    
    if score >= goal:
        minprob = min(minprob,solvedprob)

print(minprob)

Solution (Python):
D,G = [int(s) for s in input().split()]
data = [[0 for i in range(3)] for j in range(D)]
s = []
for i in range(D):
    data[i][0] = (i+1)*100
    data[i][1],data[i][2] = [int(s) for s in input().split()]
data.reverse()

for i in range(1 << D):
    fl = False
    seq = 0
    sum = 0
    
    for j in range(D):
        if ((i >> j) & 1) == 1:
            sum += data[j][0]*data[j][1] + data[j][2]
            seq += data[j][1]
    if sum < G:
        
        for j in range(D):
            
            if ((i >> j) & 1) == 0:
                for k in range(data[j][1]):
                    if sum >= G:
                        fl = True
                        break
                    sum += data[j][0]
                    seq += 1
                if fl:break
    s.append(seq)
    
        
    
print(min(s))

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

k = [list(map(int, input().split())) for i in range(d)]
l = []
for i in range(1, d + 1):
    l.append(k[-i])
k = l



combined1 = []
for i in range(d):
    combined1.append([k[i][0] * (d - i) * 100 + k[i][1]])
ansli = []
for i in range(1 << d):
    output = []
    ot = []
    for j in range(d):
        if ((i >> j) & 1) == 1:
            output.append(k[j] + combined1[j])
            ot.append(j)
    
    sum = 0
    anscnt = 0
    for m in output:
        sum += m[2]
        anscnt += m[0]
    if sum >= g:
        ansli.append(anscnt)
    else:
        for v in range(d):
            if v not in ot:
                diffyen = g - sum
                tmp = (diffyen + 100 * (d - v) - 1) // (100 * (d - v))
                if tmp < k[v][0]:
                    ansli.append(anscnt + tmp)
                break
print(min(ansli))

Solution (Python):
import numpy as np
import itertools
import math

D, G = tuple(map(int, input().split()))

p_c_list = np.array([tuple(map(int, [100 * (i + 1)] + input().split())) for i in range(D)])

masks = itertools.product([False, True], repeat=len(p_c_list))

ret = np.inf
for mask in masks:
  maskedarr = p_c_list[np.array(mask), :]
  comp_sum = (maskedarr[:, 0] * maskedarr[:, 1] + maskedarr[:, 2]).sum()
  suc_num = maskedarr[:, 1].sum()
  if comp_sum < G:
    amari = (G - comp_sum) / p_c_list[~np.array(mask), 0][-1]
    if amari < p_c_list[~np.array(mask), 1][-1]:
      if ret > suc_num + amari:
        ret = suc_num + amari
    else:
      continue
  elif suc_num < ret:
    ret = suc_num
  else:
    continue
    
print(int(math.ceil(ret)))

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

ans = float("inf")
for bit in range(1 << D) :
    AC = 0
    score = 0
    for k in range(D) :
        if bit & (1 << k) :
            score += 100*(k+1)*L[k][0]+L[k][1]
            AC += L[k][0]
    if score >= G :
        ans = min(ans,AC)
        continue
    for k in range(D-1,-1,-1) :
        if bit & (1 << k) :
            continue
        if (score + 100*(k+1)*L[k][0]) < G :
            score += 100*(k+1)*L[k][0]
            AC += L[k][0]
        else :
            res = G - score
            while res > 0 :
                res -= 100*(k+1)
                AC += 1
            ans = min(ans,AC)
            break
print(ans)

Solution (Python):
d,g = map(int,input().split())
pc = [list(map(int,input().split())) for _ in range(d)]
res = 10**10
for bit in range(1 << d):
    score = 0
    prob = 0
    used = [False] * d
    for i in range(d):
        if bit & 1:
            used[i] = True
            score += pc[i][1]
            score += (i + 1) * 100 * pc[i][0]
            prob += pc[i][0]
        bit >>= 1
    dd = []
    for i in range(d-1,-1,-1):
        if not used[i]:
            dd.append([(i+1) * 100, pc[i][0]])
    pivot = 0
    flag = True
    while score < g:
        if pivot == len(dd):
            flag = False
            break
        if dd[pivot][1] == 0:
            pivot += 1
            continue
        else:
            score += dd[pivot][0]
            prob += 1
            dd[pivot][1] -= 1
    if not flag:
        continue
    res = min(res, prob)
print(res)

Solution (Python):
ranknum, goal = list(map(int, input().split()))
probnum = [0] * ranknum
bonus = [0] * ranknum
compscore = [0] * ranknum

for i in range(ranknum):
    probnum[i], bonus[i] = list(map(int, input().split()))
    
    compscore[i] = 100 * (i + 1) * probnum[i] + bonus[i]

from itertools import product
from math import ceil


minprob = 1001


for c in product(range(2), repeat=ranknum):
    score = 0
    solvedprob = 0
    notcompedindex = -1

    
    for i in range(ranknum):
        if c[i] == 1:
            score += compscore[i]
            solvedprob += probnum[i]
        
        else:
            notcompedindex = i

    
    
    if score < goal and score + 100 * (notcompedindex + 1) * (probnum[notcompedindex] - 1) >= goal:
        solvedprob += ceil((goal - score) / (100 * (notcompedindex + 1)))
        score += ceil((goal - score) / (100 * (notcompedindex + 1))) * 100 * (notcompedindex + 1)

    
    if score >= goal:
        minprob = min(minprob, solvedprob)

print(minprob)

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

min_c = float('inf')
for i in range(2**d):
    cnt = 0
    score = 0
    for j in range(d):
        if 1 << j & i:
            cnt += problems[j][1]
            score += problems[j][0] * problems[j][1] + problems[j][2]
    if score >= g:
        min_c = min(min_c, cnt)
    for j in range(d):
        if not (1 << j & i):
            need = max(0, (g - score + problems[j][0] - 1) // problems[j][0])
            if problems[j][1] >= need:
                min_c = min(min_c, cnt + need)
print(min_c)

Solution (Python):
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())
    p[i] = p_i
    c[i] = c_i

cnt = 100000
for i in range(1 << D):
    num = -1
    score = 0
    cnt_ = 0
    for j in range(D):
        if (i >> j) % 2 == 1:
            score += p[j] * 100 * (j+1) + c[j]
            cnt_ += p[j]
        else:
            num = j
    if score >= G:
        cnt = min(cnt, cnt_)
    else:
        if num == -1:
            pass
        else:
            n = p[num]
            while n > 0:
                n -= 1
                score += (num+ 1) * 100
                cnt_ += 1
                if score >= G:
                    cnt = min(cnt, cnt_)
                    break
print(cnt)

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 = []
def greedy(count,comp,diff):
    ret = -1
    for i in range(d-1,-1,-1):
        if not(i in comp):
            if (p[i]-1)*(i+1)*100 >= diff:
                ret = count + diff//((i+1)*100) + (diff % ((i+1)*100) != 0)
                break
    return ret

def search(i,score,count,comp):
    if i == d:
        if score >= g:
            ans.append(count)
            return
        res = greedy(count,comp,g - score)
        if res != -1:
            ans.append(res)
    else:
        search(i+1,score,count,comp)
        comp.append(i)
        search(i+1,score+p[i]*(i+1)*100+c[i],count+p[i],comp)
search(0,0,0,[])
print(min(ans))

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

ans = float("inf")
for bit in range(2 ** D) :
    score = 0
    AC = 0
    for k in range(D) :
        if bit & (1 << k) :
            p,c = L[k]
            score += c
            AC += p
            score += p*(k+1)*100
    if score >= G :
        ans = min(ans,AC)
        continue
    for k in range(D-1,-1,-1) :
        if bit & (1 << k) :
            continue
        p,c = L[k]
        if (score + p*(k+1)*100) < G :
            score += p*(k+1)*100
            AC += p
        else :
            rem = G - score
            AC += rem // ((k+1)*100)
            if rem % ((k+1)*100) != 0 :
                AC += 1
            ans = min(ans,AC)
            break
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)
ans = float("inf")
for i in range(1 << D) : 
    ct = 0 
    score = 0
    for j in range(D) :
        if (i >> j) & 1 : 
            score += C[j] 
            score += P[j] * (j+1) * 100 
            ct += P[j] 
    for j in range(D-1,-1,-1) : 
        if score >= G : 
            break
        if (i >> j) & 1 : 
            continue
        g = (j+1)*100
        got = (G-score)//g
        score += min(got,P[j])*g
        ct += min(got,P[j])
    ans = min(ans, ct)
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)

ans = float("inf")
for i in range(1 << D) :
    ct = 0
    score = 0
    for j in range(D) :
        if i >> j&1 :
            score += C[j]
            score += P[j] * (j+1) * 100
            ct += P[j]
    for j in range(D-1, -1, -1) :
        if i >> j&1 :
            continue
        if score >= G :
            break
        g = (j+1)*100
        got = (G-score+g-1)//g
        score += min(got, P[j])*g
        ct += min(got, P[j])
    ans = min(ans, ct)
print(ans)

Solution (Python):
D,G=map(int,input().split())
A=[]
for i in range(D):
    p,c=map(int,input().split())
    A.append([p,c])
a=10**9
for j in range(2**D):
    b=format(j, 'b')
    B="0"*(D-len(b))+str(b)
    S=[]
    N=[]
    for k in range(D):
        S.append((A[k][0]*(k+1)*100+A[k][1])*int(B[-k-1]))
        N.append(A[k][0]*int(B[-k-1]))
        if sum(S)>=G:
            s=sum(N)
            if a>s:
                a=s
        else:
            for l in range(D):
                if B[l]=="0" and (G-sum(S))<=((D-l)*100)*(A[-l-1][0]-1):
                    s=sum(N)+((G-sum(S))//((D-l)*100))+min(1,((G-sum(S))%((D-l)*100)))
                    if a>s:
                        a=s
                    break
print(a)

Solution (Python):
from collections import defaultdict

D,G=map( int, raw_input().split() )
P=[ map( int, raw_input().split() ) for i in range(D) ] 

N=10**6
dp= [  float("inf") for i in range(N+1) ]
dp[0]=0

for idx, x  in enumerate(P):
	m=idx+1	
	p,c=x[0], x[1]/100
	for i in range(N,-1,-1):
		if dp[i]!=float("inf"):
			for j in range(p,-1,-1):	
				if j==p:
					dp[i+m*j+c]=min( dp[i+m*j+c] , dp[i]+j )
				else:
					dp[i+m*j]=min( dp[i+m*j] , dp[i]+j )



ans=float("inf")

for i in range(G/100,N):
	ans=min(ans, dp[i])

print ans

Solution (Python):
from collections import defaultdict

D,G=map( int, raw_input().split() )
P=[ map( int, raw_input().split() ) for i in range(D) ] 

N=10**6
dp= [  float("inf") for i in range(N+1) ]
dp[0]=0

for idx, x  in enumerate(P):
	m=idx+1	
	p,c=x[0], x[1]/100
	for i in range(N,-1,-1):
		if dp[i]!=float("inf"):
			for j in range(p,-1,-1):	
				if j==p:
					dp[i+m*j+c]=min( dp[i+m*j+c] , dp[i]+j )
				else:
					dp[i+m*j]=min( dp[i+m*j] , dp[i]+j )



ans=float("inf")

for i in range(G/100,N):
	ans=min(ans, dp[i])

print ans

Solution (Python):
from collections import defaultdict

D,G=map( int, raw_input().split() )
P=[ map( int, raw_input().split() ) for i in range(D) ] 

N=10**6
dp= [   [ float("inf") for i in range(N+1)] for idx in range(D+1)  ]
dp[0][0]=0

for idx, x  in enumerate(P):
	m=idx+1	
	p,c=x[0], x[1]/100
	for i in range(N,-1,-1):
		if dp[idx][i]!=float("inf"):
			for j in range(p,-1,-1):	
				if j==p:
					dp[idx+1][i+m*j+c]=min( dp[idx+1][i+m*j+c] , dp[idx][i]+j )
				else:
					dp[idx+1][i+m*j]=min( dp[idx+1][i+m*j] , dp[idx][i]+j )


ans=float("inf")

for i in range(G/100,N):
	ans=min(ans, dp[-1][i])

print ans

Solution (Python):
def lastjudge(L, i, G):
  mi = 1000
  for j in L:
    if j[4] == 0:
      if j[3] < G:
        continue
      elif j[3] - j[1] > G:
        t = -(-G // j[2])
      else:
        t = j[0]
      if mi > t:
        mi = t
  return mi
def judge(L, i, G):
  if i+1 < len(L):
    m = judge(L, i+1, G)
    if L[i][3] >= G:
      if L[i][3] - L[i][1] > G:
        t = -(-G // L[i][2])
      else:
        t = L[i][0]
    else:
      G -= L[i][3]
      L[i][4] = 1
      t = L[i][0] + judge(L, i+1, G)
    return min(t, m)
  else:
    m = lastjudge(L, i, G)
    if L[i][3] < G:
      G -= L[i][3]
      L[i][4] = 1
      t = L[i][0] + lastjudge(L, i, G)
    elif L[i][3] - L[i][1] > G:
      t = -(-G // L[i][2])
    else:
      t = L[i][0]
    return min(t, m)
 
D, G = list(map(int,input().split()))
L = []
for i in range(D):
  L.append(list(map(int, input().split())))
  L[i].append((i+1) * 100)
  L[i].append(L[i][0] * L[i][2] + L[i][1])
  L[i].append(0)
print(judge(L, 0, G))

Solution (Python):
import math
d,g = map(int,input().split())
g //= 100
p = [0 for _ in range(d)]
c = [0 for _ in range(d)]
sump = [0 for _ in range(d)]
for i in range(d):
    p[i],c[i] = map(int,input().split())
    c[i] = c[i]//100
    sump[i] = (i+1)*p[i] + c[i]

min = 10000


for i in range(1<<d):
    sum = 0
    qst = 0
    maxq = 1
    for j in range(d):
        if i>>j & 1:
            sum += sump[j]
            qst += p[j]
        elif maxq < j+1:
            maxq = j+1
    if sum + maxq*p[maxq-1] < g:
        continue
    else:
        if min > max(0,math.ceil((g-sum)/maxq)) + qst:
            min = max(0,math.ceil((g-sum)/maxq)) + qst

print(min)

Solution (Python):
from itertools import product
import math

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

P = [0] * D
C = [0] * D
for i in range(D):
    P[i], C[i] = [int(_) for _ in input().split()]

V = []
for i in range(D):
    v = P[i] * (i + 1) * 100 + C[i]
    V.append(v)

max_P = sum(P)


def func(bit_pattern):
    score = 0
    tmp = 0
    for i in range(D):
        if bit_pattern[i]:
            score += V[i]
            tmp += P[i]

    if score >= G:
        return tmp

    res = G - score

    for i in reversed(range(D)):
        if not bit_pattern[i]:
            x = math.ceil(res / ((i + 1) * 100))
            if x < P[i]:
                return tmp + x

    return max_P


ans = max_P
for bit_pattern in product(range(2), repeat=10):

    tmp = func(bit_pattern)
    ans = min(ans, tmp)

print(ans)

Solution (Python):
import itertools

D, G = map(int, input().split())
P = [0 for _ in range(D)]
C = [0 for _ in range(D)]
for i in range(D):
    p, c = map(int, input().split())
    P[i] = p
    C[i] = c

ans = 10 ** 10
for mask in itertools.product((0, 1), repeat=D):
    myscore = 0
    soloved_num = 0
    incomplete_index = 0
    for i, j in enumerate(mask):
        if j == 0:
            incomplete_index = i
        else:
            myscore += P[i] * (i + 1) * 100 + C[i]
            soloved_num += P[i]
    if myscore < G:
        for n in range(P[incomplete_index]):
            myscore += (incomplete_index + 1) * 100
            soloved_num += 1
            if myscore >= G:
                break
    if myscore >= G:
        ans = min(ans, soloved_num)

print(ans)

Solution (Python):
def m(g, ps):
    res = 0
    i = len(ps) - 1
    while g > 0 and i >= 0:
        if ps[i] > 0:
            g -= 100 * (i + 1)
            ps[i] -= 1
            res += 1
        else:
            i -= 1
    return res if g <= 0 else 1 << 30


def main():
    d, g = map(int, input().split())
    ps = [0] * d
    cs = [0] * d
    for i in range(d):
        ps[i], cs[i] = map(int, input().split())
    qs = [p - 1 for p in ps]
    res = m(g, qs)
    for i in range(1, 1 << d):
        qs = [p - 1 for p in ps]
        g0 = 0
        m0 = 0
        for j in range(d):
            if (i >> j) & 1:
                g0 += 100 * (j + 1) * ps[j] + cs[j]
                m0 += ps[j]
                qs[j] = 0
        if g0 < g:
            res = min(res, m0 + m(g - g0, qs))
        else:
            res = min(res, m0)
    print(res)


if __name__ == '__main__':
    main()

Solution (Python):
import math
D, G = map(int, input().split())
p = {}
c = {}
for i in range(D):
	p[i], c[i] = map(int, input().split())
ans = 9999
for i in range(1 << D):
	rest_max = -1
	sum = 0
	n = 0
	for j in range(D):
		if (i >> j) & 1 == 1:
			sum = sum + p[j] * (j + 1) * 100 + c[j]
			n = n + p[j]
		else:
			rest_max = j
	if rest_max == -1:
		ans = min(ans, n)
		continue
	if sum + (p[rest_max] - 1) * (rest_max + 1) * 100 < G:
		continue
	n = n + max(math.ceil((G - sum) / 100 / (rest_max + 1)), 0)
	ans = min(ans, n)
	
print(ans)

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

for i in range(1 << d): 
    score = 0
    num = 0
    rest = 0
    for j in range(d): 
        if ((i >> j) & 1) == 1: 
            score += p[j][0] * 100 * (j + 1) + p[j][1]
            num += p[j][0]
        else:
            rest = j
    if score < g:
        need = (g - score - 1) // (100*(rest+1)) + 1
        if need > p[rest][0] - 1: 
            continue
        else:
            num += need
    ans = min(ans, num)
print(ans)

Solution (Python):
d, g = map(int, input().split())
o, c = zip(*[map(int, input().split()) for _ in range(d)])

comp = [(i+1)*o[i]+c[i]//100 for i in range(d)]

G = g//100


ans = sum(o)

for j in range(2**d):
    tmp = bin(j)
    ope = tmp[2:len(tmp)].zfill(d)

    now = 0  
    f = 1
    num = 0  
    re = [[0, 0]]  

    for i in range(d):
        if ope[i] == '1':
            now += comp[i]
            num += o[i]
        else:
            re.append([(i+1)*(o[i]-1), i+1])

        re.sort()
        re.reverse()

    if now < G:
        if now+re[0][0] < G:
            
            now = sum(o)
            f = -1
        else:
            
            K = (G - now)//re[0][1]

            
            if ((G-now) % re[0][1] > 0):
                K = K+1
            num += K
    if num < ans and f > 0:
        ans = num
print(ans)

Solution (Python):
import math

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

ret = 10000
for i in range(1 << D):
    buf = 0
    s = 0
    for k in range(D):
        if i & (1 << k):
            buf += P[k][0]
            s += P[k][0] * (k + 1) * 100 + P[k][1]
    if s < G:
        f = False
        for k in reversed(range(D)):
            if not i & (1 << k):
                t = math.ceil((G - s) / ((k + 1) * 100))
                if t <= P[k][0] - 1:
                    buf += t
                    f = True
                    break
        if not f:
            continue
    ret = min(ret, buf)

print(ret)

Solution (Python):
D, G = map(int, input().split(" "))
P, C = zip(*[map(int, input().split(" ")) for _ in range(D)])

sum_points = [100*(i+1)*P[i] + C[i] for i in range(D)]
P = list(P) + [0]
C = list(C) + [0]

min_num = 10**9
for i in range(1<<D):
	first_zero = -1
	point = 0
	q_count = 0
	for j in range(D-1, -1, -1):
		if (i>>j)%2 == 1:
			point += sum_points[j]
			q_count += P[j]
		elif first_zero == -1:
			first_zero = j
	
	for j in range(P[first_zero]):
		if point >= G:
			min_num = min(min_num, q_count)
			break
		point += 100*(first_zero+1)
		q_count += 1
	point += C[first_zero]
	
	if point >= G:
		min_num = min(min_num, q_count)

print(min_num)

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

ans = 1000
for i in range(1 << d):
	score = 0
	num = 0
	rest = 0
	for j in range(d):
		if ((i >> j) & 1) == 1:
			score += pc[j][0]*100*(j+1) + pc[j][1]
			num += pc[j][0]
		else:
			rest = j
	if score < g:
		need = (g-score-1)//(100*(rest+1)) + 1
		if need > pc[rest][0]-1:
			continue
		else:
			num += need
	ans = min(ans, num)

print(ans)

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

p = []
c = []
ma = []

for i in range(D):
    tmp = list(map(int, input().split()))
    p.append(tmp[0])
    now = (i+1)*tmp[0]+tmp[1]//100
    ma.append(now)

ans = sum(p)

for j in range(2**(D)):
    tmp = bin(j)
    ope = tmp[2:len(tmp)].zfill(D)

    now = 0
    f = 1

    num = 0
    re = [[0, 0]]

    for i in range(D):
        if ope[i]=='1':
            now = now + ma[i]
            num = num + p[i]
        else:
            re.append([(i+1)*(p[i]-1), i+1])
    
    re.sort()
    re.reverse()
    
    
    if now<(G//100):
        if now+re[0][0]<(G//100):
            now = sum(p)
            f = -1
        else:
            K = ((G//100)-now)//(re[0][1])
            
            if ((G//100)-now)%(re[0][1])>0:
                K = K+1
            
            num = num + K

    if num<ans and f>0:
        ans = num
        

print(ans)

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

ans=float('inf')
for i in range(1<<d):
    all_bits=[]
    for j in range(d):
        all_bits.append((i>>j)&1)
    cnt=0
    score=0
    maxscore_problem=0
    for k in range(d):
        if all_bits[k]==1:
            score+=100*(k+1)*l[k][0]+l[k][1]
            cnt+=l[k][0]
        else:
            maxscore_problem=k
    if g<=score:
        ans=min(ans,cnt)
    elif -(-(g-score)//(100*(maxscore_problem+1)))<l[maxscore_problem][0]:
        ans=min(ans,cnt+(-(-(g-score)//(100*(maxscore_problem+1)))))
print(ans)

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

score_map = {}
for i in range(D):
    score_map[i] = list(map(int, input().split()))

result_list = []
for bit in range(1 << D):
    sum = 0
    result = 0
    not_used = D
    for i in range(D):
        if 1 & bit >> i:
            sum += score_map[i][1] + 100 * (i + 1) * score_map[i][0]
            result += score_map[i][0]
        else:
            not_used = i

    if not_used != D:
        for p in range(score_map[not_used][0]):
            if sum + (not_used + 1) * 100 * p >= G:
                result_list.append(result + p)

    else:
        if sum >= G:
            result_list.append(result)

print(min(result_list))

Solution (Python):
from math import ceil

D, G = map(int, input().split())
P, C = [], []
for _ in range(D):
    tp, tc = map(int, input().split())
    P.append(tp)
    C.append(tc)

ans = float('inf')
for mask in range(1 << D):
    s = 0
    num = 0
    rest_max = -1
    for i in range(D):
        if mask >> i & 1:
            s += 100 * (i + 1) * P[i] + C[i]
            num += P[i]
        else:
            rest_max = i
    if s < G:
        rest_max_point = 100 * (rest_max + 1)
        need = ceil((G - s) / rest_max_point)
        if need < P[rest_max]:
            num += need
        else:
            continue
    ans = min(ans, num)

print(ans)

Solution (Python):

from itertools import combinations

d,g = map(int, input().split())
p = []
c = []
for _ in range(d):
    a,b = map(int, input().split())
    p.append(a)
    c.append(b)

res = 100*10
for i in range(d+1):
    for cc in combinations(range(d), i):
        t = 0
        s = 0
        for pi in cc:
            s += (pi+1)*100*p[pi] + c[pi]
            t += p[pi]
        if s<g:
            pi = max(set(range(d)) - set(cc))
            for j in range(1,p[pi]):
                s += (1+pi)*100
                t += 1
                if s>=g:
                    break
        if s>=g:
            res = min(res, t)
print(res)

Solution (Python):
D, G = (int(i) for i in input().split())
P = []
C = []
for a in range(D):
    pp, cc = (int(i) for i in input().split())
    P.append(pp)
    C.append(cc)

reslis = []
for i in range(2**D):
    su = 0
    num = 0
    for j in range(D):
        if i & 2**j:
            su += C[j] + P[j] * (j+1) * 100
            num += P[j]
        else:
            pass

    for j in range(D-1, -1 ,-1):
        if G - su <= 0:
            break
        if not i & 2**j:
            if G - su >  (P[j] - 1) * (j+1) * 100:
                su += (P[j] - 1) * (j+1) * 100
                num += P[j] - 1
            else:
                num += (G - su +  (j+1) * 100 - 1) // ( (j+1) * 100 )
                break
    else:
        continue
    reslis.append(num)

reslis.sort()
print(reslis[0])

Solution (Python):
import math

D, G = [int(x) for x in input().split()]

P = [0] * (D+1)
C = [0] * (D+1)

for i in range(D):
    p, c = [int(x) for x in input().split()]
    P[i] = p
    C[i] = c

INF = 10**10

def score_cnt(i):
    ret_score = 0
    ret_cnt = 0
    for j in range(D):
        if (1 << j) & i:
            ret_score += C[j]
            ret_score += (j + 1) * 100 *P[j]
            ret_cnt += P[j]
    return ret_score, ret_cnt


ret = INF
for i in range(2 ** D):
    score,cnt = score_cnt(i)
    
    for j in range(D):
        if score >= G:
            ret = min(ret, cnt)
        else:
            if (1 << j) & i:
                continue
            rest = G - score

            if (j+1)*100 * P[j] >= rest:
                add = math.ceil(rest / ((j+1)*100))
                ret = min(ret, cnt + add)



print(ret)

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


ans = 0
for i in range(D):
    ans += pc[i][0]

for i in range(2**D-1):
    temp_ans = 0
    temp_sum = 0
    s = '{:010b}'.format(i)[::-1]
 
    notused = -1
    for j in range(D):
        if s[j] == '1':
            temp_ans += pc[j][0]
            temp_sum += (j+1)*pc[j][0]*100 + pc[j][1]
        else:
            notused = j

    if temp_sum >= G:
        ans = min(temp_ans,ans)
    else:
        for i in range(1,pc[notused][0]):
            if (notused+1)*i*100+temp_sum >= G:
                ans = min(temp_ans+i,ans)

                break
print(ans)

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

ans = 1e100

for bit in range(1 << D):
    score = 0
    num = 0

    
    for b in range(D):
        if (bit & (1 << b)) > 0:
            score += cs[b] + ps[b] * 100 * (b + 1)
            num += ps[b]
    if score >= G:
        ans = min(ans, num)
        continue

    for b in range(D - 1, -1, -1):
        
        if (bit & (1 << b)) > 0:
            continue

        for j in range(ps[b]):
            if score >= G:
                break
            score += 100 * (b + 1)
            num += 1
    ans = min(ans, num)

print(ans)

Solution (Python):
from math import ceil

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

ans = 1000
for pat in range(2 ** D):
    score = 0
    num = 0
    for i in range(D):
        if pat & (1 << i):
            score += 100 * (i + 1) * ps[i] + cs[i]
            num += ps[i]
        else:
            iRest = i

    if score < G:
        n = ceil((G - score) / (100 * (iRest + 1)))
        if n >= ps[iRest]: continue
        num += n

    ans = min(ans, num)

print(ans)