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

Solution (Python):
import  itertools
d,g=map(int,input().split())
p=[]
c=[]
for i in range(d):
    x,y=map(int,input().split())
    p.append(x)
    c.append(y)
ans=float('inf')
def judge(tmp):
    ss=g
    count=0
    for i in range(d):
        if tmp[i]==1:
            ss-=((i+1)*p[i]*100+c[i])
            count+=p[i]
    if ss<=0:
        return count
    else:
        for i in range(d-1,-1,-1):
            if tmp[i]==0:
                if ss%((i+1)*100)==0:
                    fgh=ss//((i+1)*100)
                else:
                    fgh=1+ss//((i+1)*100)
                if fgh>=p[i]:
                    count+=float('inf')
                else:
                    count+=fgh
                ss -= fgh * ((i + 1) * 100)
            if ss<=0:
                return count
        return count+float('inf')
nums=[0,1]
for sd in itertools.product(nums,repeat=d):
    pat=list(sd)
    sdf=judge(pat)
    ans=min(ans,sdf)
print(ans)

Solution (Python):
import  itertools

d,g=map(int,input().split())
p=[]
c=[]

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

ans=float('inf')

def judge(tmp):
    ss=g
    count=0

    for i in range(d):
        if tmp[i]==1:
            ss-=((i+1)*p[i]*100+c[i])
            count+=p[i]
    if ss<=0:

        return count
    else:
        for i in range(d-1,-1,-1):
            if tmp[i]==0:
                if ss%((i+1)*100)==0:
                    fgh=ss//((i+1)*100)
                else:
                    fgh=1+ss//((i+1)*100)

                if fgh>=p[i]:
                    count+=float('inf')
                else:
                    count+=fgh

                ss -= fgh * ((i + 1) * 100)
            if ss<=0:
                
                return count
       
        return count+float('inf')

nums=[0,1]
for sd in itertools.product(nums,repeat=d):
    pat=list(sd)
    sdf=judge(pat)
    ans=min(ans,sdf)

print(ans)

Solution (Python):
d,G=map(int,input().split())
l=[list(map(int,input().split())) for i in range(d)]
ans=1000
for i in range(2**d):
    g=0
    t=0
    ncp=[1,0]
    for j in range(d):
        if i>>j&1:
            g+=l[j][0]*(j+1)*100+l[j][1]
            t+=l[j][0]
        else:
            ncp=[(j+1)*100,l[j][0]]
    t+=max(min(-(-(G-g)//ncp[0]),ncp[1]),0)
    g+=max(min(-(-(G-g)//ncp[0]),ncp[1]),0)*ncp[0]
    if g>=G:
        ans=min(ans,t)
print(ans)

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


ans = int(1e10)
for i in range(2 ** D):
    zen = []
    atemp = 0
    ktemp = 0
    for j in range(D):
        if (i >> j) & 1:
            zen.append(True)
        else:
            zen.append(False)
    for n, tf in enumerate(zen):
        if tf:
            atemp += pc[n][0] * (n+1) * 100 + pc[n][1]
            ktemp += pc[n][0]
        else:
            hanpa = n
    if atemp >= G:
        ans = min(ans, ktemp)
    else:
        if atemp + pc[hanpa][0]*(hanpa+1)*100 < G:
            continue
        else:
            if (G - atemp) % ((hanpa+1)*100) == 0:
                ans = min(ans, ktemp + ((G - atemp) // ((hanpa+1)*100)))
            else:
                ans = min(ans, ktemp + ((G - atemp) // ((hanpa+1)*100)) + 1)

print(ans)

Solution (Python):
import math

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

digit = "0"+str(D)+"b"
ans = float("INF")
for i in range(2**D):
  flags = list(str(format(i,digit)))
  points = 0
  problems = 0
  last0 = -1
  
  for j in range(D):
    if int(flags[j]):
      points += pc[j][0]*100*(j+1)+pc[j][1]
      problems += pc[j][0]
    else:
      last0 = j
  if points >= G:
    ans = min(ans,problems)
    continue
  elif last0 == -1:
    continue
  else:
    r = G-points
    need = math.ceil(r/(100*(last0+1)))
    if need > pc[last0][0]-1:
      continue
    else:
      ans = min(ans,problems+need)
      
print(ans)

Solution (Python):
def main():
    import sys
    input = sys.stdin.readline
    sys.setrecursionlimit(10**7)
    from collections import Counter, deque
    
    from itertools import combinations, permutations, accumulate, groupby
    
    from bisect import bisect_left,bisect_right
    from heapq import heapify, heappop, heappush
    from math import floor, ceil
    

    
    

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

    
    for s in range(1<<d):
        total = 0
        n = 0
        
        for i in range(d):
            if (s>>i) & 1:
                total += 100 *(i+1)*pc[i][0] + pc[i][1]
                n += pc[i][0]

        if total >= g:
            res = min(res, n)
        else:
            for i in range(d-1, -1, -1):
                if ((s>>i) & 1) == 0:
                    if 100*(i+1)*(pc[i][0]-1) >= g-total:
                        res = min(res, n+ceil((g-total)/(100*(i+1))))
                        break
                    else:
                        total += 100*(i+1)*(pc[i][0]-1)
                        n += pc[i][0] - 1
    print(res)

if __name__ == '__main__':
    main()

Solution (Python):
def cont(ob,j):
    if (ob <= 0):
            return 0
    for i in range(len(j)):
        ob -= j[i]
        if (ob <= 0):
            return i+1
    return 9999
 
d,ob = map(int,input().split())
lst = []
point = []
kai = [[0 for i in range(ob//100)] for j in range(d)]
 
for i in range(d):
    lst =[]
    a = list(map(int,input().split()))
    for j in range(a[0]):
        lst.append((i+1)*100)
    lst[j] += a[1]
    point.append(lst)
 
 
for i in range(len(kai)):
    for j in range(len(kai[0])):
        if i == 0:
            kai[i][j] = cont((j+1)*100,point[i])
        else:
            if(sum(point[i])<(j+1)*100):
                a = kai[i-1][j]
                b = len(point[i]) + kai[i-1][j-sum(point[i])//100 ]
                if a>b:
                    kai[i][j] = b
                else:
                    kai[i][j] = a
            else:
                a = kai[i-1][j]
                b = cont((j+1)*100,point[i])
                if a>b:
                    kai[i][j] = b
                else:
                    kai[i][j] = a
        
 

print(kai[len(kai)-1][len(kai[0])-1])

Solution (Python):
def main():
    D, G = map(int, input().split())
    PC = [tuple(map(int, input().split())) for _ in range(D)]
    PC = [(p, c // 100) for p, c in PC]
    G //= 100
    m = 10 * 100
    for i in range(2 ** D):
        g = 0
        t = 0
        k = -1
        for j, (p, c) in enumerate(PC):
            if (1 << j) & i:
                g += (j + 1) * p + c
                t += p
            else:
                k = j
        if g >= G:
            m = min(m, t)
            continue
        p, c = PC[k]
        if (k + 1) * p + g < G:
            continue
        m = min(m, t + (G - g + k) // (k + 1))
    return m

print(main())

Solution (Python):

from scipy.sparse.csgraph import shortest_path, floyd_warshall, dijkstra, bellman_ford, johnson, minimum_spanning_tree
from scipy.sparse import csr_matrix, coo_matrix, lil_matrix
import numpy as np
from functools import reduce

from collections import deque, Counter, defaultdict
from itertools import product, permutations,combinations
from operator import itemgetter
from heapq import heappop, heappush
from bisect import bisect_left, bisect_right, bisect
from fractions import gcd
from math import ceil,floor, sqrt, cos, sin, pi, factorial
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
sys.setrecursionlimit(10**8)
INF = float('inf')
MOD = 10**9+7

def main():
  d, g = map(int, readline().split())
  pc = list(list(map(int, readline().split()))for _ in range(d))
  
  ans = INF
  
  for i in range(2**d):
    score = 0
    amari_max=0
    cnt=0
    for j in range(d):
      if (i>>j)&1:
        score += 100*(j+1)*pc[j][0] + pc[j][1]
        cnt += pc[j][0]
      else:
        amari_max = j
    for j in range(pc[amari_max][0]):
      if score>=g:
        ans = min(ans, cnt)
      score+=(amari_max + 1)*100
      cnt += 1
  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)]

ans=float('inf')
for i in range(2**D):
  score=0
  b=0
  cnt=0
  for j in range(D):
    if ((i>>j)&1):
      score+=100*(j+1)*pc[j][0]+pc[j][1]
      cnt+=pc[j][0]
    else:
      b=j
  for k in range(pc[b][0]):
    if score>=G and cnt<ans:
      ans=cnt
    score+=(b+1)*100
    cnt+=1
print(ans)

Solution (Python):
def get_min_score(flags):
    score = 0
    num_probs = 0
    for j, flag in enumerate(flags):
        if flag == '1':
            score += PC[j][1] + PC[j][0] * (j + 1) * 100
            num_probs += PC[j][0]
            if score >= G:
                return num_probs

    for j in range(len(flags) - 1, -1, -1):
        if flags[j] == '0':
            for k in range(PC[j][0]):
                score += (j + 1) * 100
                num_probs += 1
                if score >= G:
                    return num_probs
    return float('inf')


D, G = map(int, input().split())
PC = [list(map(int, input().split())) for _ in range(D)]
ans = float('inf')
for i in range(2 ** D):
    flags = bin(i)[2:].zfill(D)
    ans = min(ans, get_min_score(flags))
print(ans)

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


bins = []  
for i in range(2**d): 
    bins.append(list(str(format(i,'b')).zfill(d)))
    
ans=0
for i in range(d):
    ans +=  pc[i][0]
for i in range(2**d):
    
    tmp_num = 0
    tmp_ans = 0
    for j in range(d):
        if(bins[i][j]=='1'):
            tmp_num += pc[j][0]*100*(j+1)+pc[j][1]
            tmp_ans += pc[j][0]
        else:
            rest_max = j
    if(tmp_num>=g):
        ans = min(tmp_ans,ans)
    else:
       
        plus = -(-(g-tmp_num)//(100*(rest_max+1)))
        if(plus<pc[rest_max][0]):
            tmp_ans += plus
            ans=min(tmp_ans,ans)
        
    
print(ans)

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

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

for i in range(2**d):
	score = 0
	count = 0
	horyu = 0
	for j in range(d):
		if ((i >> j) & 1):
			score += (j+1)*p[j]*100 + c[j]
			count += p[j]
		else:
			horyu = j
	for _ in range(p[horyu]):
		if score >= g and count < ans:
			ans = count
		score += (horyu + 1) * 100
		count += 1

print(ans)

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

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

for i in range(2**d):
	score = 0
	count = 0
	horyu = 0
	for j in range(d):
		if ((i >> j) & 1):
			score += (j+1)*p[j]*100 + c[j]
			count += p[j]
		else:
			horyu = j 
	for i in range(p[horyu]):
		if score >= g and count < ans:
			ans = count
		score += (horyu + 1) * 100
		count += 1

print(ans)

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

ans = float("inf")


for bit in range(1<<d):
    count = 0
    sum = 0
    nokori = set(range(1,d+1))

    for i in range(d):
        if bit & (1<<i):
            sum +=pc[i][0]*(i+1)*100+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):
Amount_problem, Goal_point = map(int, input().split())
NumPro_ConpBonus = [[int(_) for _ in input().split()] for i in range(Amount_problem)]

min_num_ans = 1100
for i_binary in range(2**Amount_problem):
    num_ans = 0
    now_point = 0

    
    for i_position in range(Amount_problem):
        if (i_binary >> i_position) & 1 == 0:
            continue

        now_point += NumPro_ConpBonus[(Amount_problem-1) - i_position][1] \
            + 100*(Amount_problem-i_position)*NumPro_ConpBonus[(Amount_problem-1) - i_position][0]

        num_ans += NumPro_ConpBonus[(Amount_problem-1) - i_position][0]

    if now_point < Goal_point:
        for i_position in range(Amount_problem):
            if (i_binary >> i_position) & 1 == 1:
                continue

            for add_num_ans in range(1, NumPro_ConpBonus[(Amount_problem-1) - i_position][0]):
                if (now_point + 100*(Amount_problem-i_position)*add_num_ans) >= Goal_point:
                    num_ans += add_num_ans
                    min_num_ans = min(min_num_ans, num_ans)
    else:
        min_num_ans = min(min_num_ans, num_ans)

print(min_num_ans)

Solution (Python):
import sys
import math

def resolve():
    D, G = list(map(int, input().split(" ")))
    P = []
    C = []
    for i in range(D):
        p, c = list(map(int, input().split(" ")))
        P.append(p)
        C.append(c)

    mincnt = float("Inf")
    for bits in range(1<<D):
        score = 0
        cnt = 0
        
        for odr in range(D):
            if (bits & (1<<odr)):
                score += (P[odr] * 100 * (odr+1) + C[odr])
                cnt += P[odr]
        if score >= G:
            mincnt = min(mincnt, cnt)
        else:
            for odr in range(D-1, -1, -1):
                if (bits & (1<<odr)):
                    continue
                for j in range(P[odr]):
                    if score >= G:
                        break
                    score += (odr+1) * 100
                    cnt += 1
            mincnt = min(mincnt, cnt)
    print(mincnt)

if '__main__' == __name__:
    resolve()

Solution (Python):
import copy

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

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


answer=10**9
for i in range(2**D):
  bit=[0]*D
  ii=i
  for j in range(D):
    bit[j]=ii%2
    ii//=2
  
    
  pl=copy.deepcopy(prob_list)
  cnt=0
  score=0  
  for i in range(D):
    if bit[i]==1:
      cnt+=pl[i][0]
      score+=pl[i][0]*100*(i+1)+pl[i][1]
      pl[i][0]=0

  if cnt>=answer:
    continue
      
  if score>=G:
    answer=min(answer,cnt)
    
  else:
    for i in reversed(range(D)):
      if pl[i][0]==0:
        continue
      
      while(pl[i][0]>0):
        pl[i][0]-=1
        cnt+=1
        score+=100*(i+1)
        if score>=G:
          break    
      if pl[i][0]==0:
        score+=pl[i][1]
        
      if score>=G:
        break

    answer=min(answer,cnt)
    
      
print(answer)

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

min_problem = 1100
for i_num in range(2 ** d):
    score = 0
    num_problem = 0
    for i_pos in range(d):
        if (i_num >> i_pos) & 1 == 0:
            continue
        score += pc[d-i_pos-1][1] + (d-i_pos)*100*pc[d-i_pos-1][0]
        num_problem += pc[d-i_pos-1][0]
    
    if score < g:
        for j_pos in range(d):
            if (i_num >> j_pos) & 1 == 0:
                add_position = d-j_pos-1
                break
        for j_problem_ammount in range(1, pc[add_position][0]):
            add_score = score + (add_position+1)*100*j_problem_ammount
            if add_score >= g:
                min_problem = min(min_problem, num_problem+j_problem_ammount)
                break
    else:
        min_problem = min(min_problem, num_problem)

print(min_problem)

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


ans = pow(100,10)


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] * (i+1)*100 + 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):
import math
d, g = map(int, input().split())
p = []
c = []
for _ in range(d):
    a, b  = map(int, input().split())
    p.append(a)
    c.append(b)

min_cnt = 1000
for i in range(2**d):
    cnt = 0
    point = 0
    idx = 0
    for j in range(d):
        if i>>j & 1:
            cnt += p[j]
            point += (j+1)*100*p[j] + c[j]
        else:
            idx = j
    if point>=g and min_cnt>=cnt:
        min_cnt = cnt
    else:
        q = point+(idx+1)*100*(p[idx]-1)
        if q>=g:
            count = max(math.ceil((g-point)/((idx+1)*100)),0)
            cnt += count
            if min_cnt>=cnt:
                min_cnt=cnt
         
print(min_cnt)

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

min_kaisu = 999999999

for pattern in range(1 << D):
    score = 0
    kaisu = 0
    nokori_max = 0
    for i in range(1, D+1):
        if pattern & 1 << i-1:
            score += pc[i][0] * (i) * 100 + pc[i][1]
            kaisu += pc[i][0]
        else:
            nokori_max = i
    
    if score >= G:
        min_kaisu = min(min_kaisu, kaisu)
        continue
    
    if score + nokori_max * 100 * (pc[nokori_max][0] - 1) >= G:
        kaisu += -(-(G - score) // (nokori_max * 100))
        min_kaisu = min(min_kaisu, kaisu)
    else:
        continue
    
print(min_kaisu)

Solution (Python):
D, G = map(int,input().split())
Alist = [input().split() for i in range(D)]
for i in range(D):
    for j in range(2):
        Alist[i][j] = int(Alist[i][j])
m = 0
s = 0
c = 0
for i in range(D):
    m = m + Alist[i][0]
p = []
q = []
h = []
t = 0
v = 100
for i in range(D):
    p.append(100*(i+1)*Alist[i][0]+Alist[i][1])
while len(p) < 10:
        p.append(0)
for i in range(2**D):
    c = 0
    s = 0
    r = 0
    x = list(format(i,'b'))
    for i in range(len(x)):
        x[i] = int(x[i])
    x.reverse()
    while len(x) < 10:
        x.append(0)
    for f in range(10):
        r = r + p[f]*x[f]
    for i in range(D):
        c = c + Alist[i][0]*x[i]
    x.reverse()
    while t < 10:
        if x[t] == 0:
            if (10-t) <= D: 
                v = t
                break
            else:
                t = t + 1
        else:
            t = t + 1
    if v == 100:
        h.append(m)
    else:
        while r < G:
            if s == Alist[(10-v)-1][0]:
                break
            r = r + 100*(10-v)
            s = s + 1
        if r >= G:
            h.append(s+c)
print(min(h))

Solution (Python):
import numpy

def main():
    N = [int(_) for _ in input().split()]
    D = N[0]
    G = N[1]
    Q = [[int(_) for _ in input().split()] for i in range(D)]

    arr = []
    for i in range(2 ** D):
        total_score = 0
        num_kaitou = 0
        
        for j in range(D):
            if ((i >> j) & 1 == 1):
                total_score += 100 * (j+1) * Q[j][0] + Q[j][1]
                num_kaitou += Q[j][0]
        
        if total_score >= G:
            arr.append([num_kaitou, total_score])
            continue
        
        else:
            for j in reversed(range(D)):
                increment = 100 * (j+1)
                if ((i >> j) & 1 == 0):
                    for k in range(Q[j][0]):
                        total_score += increment
                        num_kaitou += 1
                        if total_score >= G:
                            arr.append([num_kaitou, total_score])
                            break
                    else:
                        continue
                    break
    
    print(numpy.min(arr, axis=0)[0])

if __name__ == "__main__":
    main()

Solution (Python):


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

d,g = LI()
pc = [LI() for _ in range(d)]
ans = inf
for i in range(1<<d):
    tmp = -1
    count = 0
    score = 0
    flag = True
    for j in range(d):
        if i >> j & 1:
            count += pc[j][0]
            score += pc[j][1] + pc[j][0]*(j+1)*100
        else:
            tmp = max(tmp,j)
    if tmp != -1:
        if score >= g:
           pass 
        elif g - score - (pc[tmp][0]-1)*(tmp+1)*100 > 0:
            flag = False
        else:
            count += (g-score-1)//((tmp+1)*100) + 1
    else:
        if score < g:
            flag = False
    if flag:
        ans = min(ans, count)
print(ans)

Solution (Python):
import math

d,g=map(int,input().split())
pclist=[]
templist=[]
for i in range(d):
	templist=[]
	templist=list(map(int,input().split()))
	templist.append(templist[0]*100*(i+1)+templist[1])
	pclist.append(templist)

promin=1000

for i in range(2**d):
    gsum=0
    prosum=0
    maxind=100
    
    for j in range(d):
        if (i >> j)& 1:
            gsum += pclist[j][2]
            prosum += pclist[j][0]
        else:
            maxind=j
            
    
    if gsum >= g:
        if prosum <= promin:
            promin=prosum
    elif (gsum + (maxind+1)*100*(pclist[maxind][0]-1))>= g:
        prosum += math.ceil((g-gsum)/((maxind+1)*100))
        if prosum <= promin:
            promin=prosum


print(promin)

Solution (Python):


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

d,g = LI()
pc = [LI() for _ in range(d)]
ans = inf
for i in permutations(range(d)):
    score = 0
    count = 0
    for j in list(i):
        p,c = pc[j]
        if score + p*(j+1)*100 + c < g:
            score += p*(j+1)*100 + c
            count += p
            continue
        elif score + p*(j+1)*100 >= g:
            count += (g-score-1)//((j+1)*100)+1
            break
        elif score + p*(j+1)*100 + c >= g:
            count += p
            break
    ans = min(ans,count)
print(ans)

Solution (Python):

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


ans = 10 ** 4

for i in range(2**D):
  points = 0
  num = 0
  idx = -1
  for d in range(D):
    
    if i>>d & 1:
      points += pc[d][0]*(d+1) + pc[d][1]
      num += pc[d][0]
    else:
      idx = d
  if points >= G:
    ans = min(ans, num)
  elif idx >= 0: 
    num_add = - (- (G - points) // (idx + 1))
    if num_add <= pc[idx][0]:
      ans = min(ans, num + num_add)

print(ans)

Solution (Python):
import math
 
d,g = [int(i) for i in input().split()]
P = []
C = []
for i in range(d):
    p,c = [int(i) for i in input().split()]
    P.append(p)
    C.append(c)

def flag(point,P,now):
    if point+100*(now+1)*(P-1) >= g: return 1
    elif point+100*(now+1)*P + C[now] >= g: return 2
    else: return 0

m = 10**9
def score(point = 0, n = 0, now=-1, remain = list(range(d))):
    global m
    if m <= n: return
    elif now == -1:
        for i in remain:
            score(point, n, i, remain)
    elif point >= g: m = n
    elif flag(point,P[now],now) == 1:
        n += math.ceil((g-point)/(100*(now+1)))
        if m > n: m = n
    elif flag(point,P[now],now) == 2:
        n += P[now]
        if m > n: m = n
    else:
        if m <= n+P[now]: return
        else:
            remain = remain[:]
            remain.remove(now)
            nxtp = point + P[now]*100*(now+1) + C[now]
            for i in remain:
                score(nxtp, n + P[now], i, remain)

score()
print(m)

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

ans=float('inf')
for i in range(2**D):
  score=0
  b=0
  cnt=0
  for j in range(D):
    if ((i>>j)&1):
      score+=100*(j+1)*pc[j][0]+pc[j][1]
      cnt+=pc[j][0]
    else:
      b=j
  for k in range(pc[b][0]):
    if score>=G and cnt<ans:
      ans=cnt
    score+=(b+1)*100
    cnt+=1
print(ans)

Solution (Python):

ans = float("inf")


def solve():

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

    
    def dfs(i, sum, count, nokori):
        global ans
        if i == d:
            
            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)
        else:
            
            dfs(i + 1, sum, count, nokori)
            dfs(i + 1, sum + pc[i][0] * (i + 1) * 100 +
                pc[i][1], count + pc[i][0], nokori - {i + 1})

    dfs(0, 0, 0, set(range(1, d + 1)))
    print(ans)


if __name__ == "__main__":
    solve()

Solution (Python):
d, g = map(int, input().split())
pc = [list(map(int, input().split())) for i in range(d)]
ans = 10000
for i in range(2**d):
  score = 0
  b = 0
  cnt = 0
  for j in range(d):
    if ((i >> j) & 1):
      score += (j+1)*pc[j][0]*100 + pc[j][1]
      cnt += pc[j][0]
    else:
      b = j
  for k in range(pc[b][0]):
    if score >= g and cnt < ans:
      ans = cnt
    score += (b+1)*100
    cnt += 1
print(ans)

Solution (Python):
import math
import collections
from operator import mul
from functools import reduce
import bisect
import string
import copy


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())

y=1000000000000000
for i in range(2**d):
    yi=0
    pi=copy.copy(p)
    gi=copy.copy(g)
    for j in range(d):
        if (i >> j) & 1:
            gi-=c[j]
            gi-=pi[j]*100*(j+1)
            yi+=pi[j]
            pi[j]=0
    ind=copy.copy(d-1)
    while gi>0 and ind>=0:
        if pi[ind]>=2:
            gi-=100*(ind+1)
            yi+=1
            pi[ind]-=1
        else: 
            ind-=1

    if gi<=0 :
        y=min(y,yi)

print(y)

Solution (Python):
d, g = map(int, input().split())
pc = [list(map(int, input().split())) for _ in range(d)]
ans = []
for i in range(2**d):
    tmp = 0
    cnt = 0
    gg = g 
    bag = []
    for j in range(d):
        if (i>>j)&1:
            
            tmp += 100*(j+1)*pc[j][0] + pc[j][1]
            cnt += pc[j][0]
            bag += [j]
    if tmp >= gg:
        ans += [cnt]
    else:
        gg -= tmp 
        for j in range(d-1, -1, -1):
            if j not in bag:
                c = (gg-1)//(100*(j+1))+1
                if 0 <= c <= pc[j][0]:
                    gg -= 100*(j+1)*c + pc[j][1]
                    cnt += c 
                if gg <= 0:
                    ans += [cnt]
                    break
        
print(min(ans))

Solution (Python):
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

def myinput():
    return map(int,readline().split())

d,g = myinput()

pc = [ list(myinput()) for _ in range(d) ]

import copy
pc2 = copy.deepcopy(pc)





ls_count = []

for i in range(2**d):
    pt = 0
    count = 0
    ls = []
    
    for j in range(d):
        if i & (2**j):
            pt = pt + 100*(j+1)*pc[j][0] + pc[j][1]
            count += pc[j][0]
        else:
            ls.append(j)
    
    if pt>=g:
        ls_count.append(count)
    else:
        r = g - pt
        while r>0:
            if len(ls)!=0:
                j = max(ls)
                if pc2[j][0]>=1:
                    r -= 100*(j+1)
                    pc2[j][0] -= 1
                    count += 1
                else:
                    count += float("inf")
                    break
        ls_count.append(count)

ans = min(ls_count)
print(ans)