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


ans = float('inf')

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

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

import itertools, math
ans = float('inf')
nums = list(range(D))
for n in range(D+1):
    for num in itertools.combinations(nums, n):

        probs, score = 0, 0
        for i in num:
            j, (p, c) = p_c_pairs[i]
            probs += p
            score += 100 * j * p + c

        if G > score:
            i = max([i for i in nums if i not in num])
            j, (p, c) = p_c_pairs[i]
            m = min(p, int(math.ceil((G - score) / (100 * j))))
            probs += m
            score += 100 * j * m
            if m == p:
                score += c

        if G <= score:
            ans = min(ans, probs)

print(ans)

Solution (Python):
def main():
    D, G, *pc = map(int, open(0).read().split())
    p = pc[::2]
    c = pc[1::2]
    
    comp = [c[i] + 100 * (i + 1) * p[i] for i in range(D)]

    def dfs(G, i):
        
        
        if i <= 0:
            
            return 1e9 + 7
        score = 0
        num = min(G // (100 * i), p[i - 1])
        if num == p[i - 1]:
            
            score = comp[i - 1]
        else:
            
            score = 100 * i * num
        if score < G:
            
            num += dfs(G - score, i - 1)
        
        return min(num, dfs(G, i - 1))
    print(dfs(G, D))


main()

Solution (Python):
def main():
    D, G, *pc = map(int, open(0).read().split())
    p = pc[::2]
    c = pc[1::2]
    
    comp = [c[i] + 100 * (i + 1) * p[i] for i in range(D)]

    def dfs(G, i):
        
        
        if i <= 0:
            
            return 1e9 + 7
        score = 0
        num = min(G // (100 * i), p[i - 1])
        if num == p[i - 1]:
            
            score = comp[i - 1]
        else:
            
            score = 100 * i * num
        if score < G:
            num += dfs(G - score, i - 1)
        return min(num, dfs(G, i - 1))
    print(dfs(G, D))


main()

Solution (Python):
def main():
    D, G, *pc = map(int, open(0).read().split())
    p = pc[::2]
    c = pc[1::2]
    
    comp = [c[i] + 100 * (i + 1) * p[i] for i in range(D)]

    def dfs(G, i):
        
        
        if i <= 0:
            
            return 1e9 + 7
        score = 0
        num = 0
        if G // (100 * i) < p[i - 1]:
            
            num = G // (100 * i)
            score = 100 * i * num
        else:
            
            num = p[i - 1]
            score = comp[i - 1]
        if score < G:
            num += dfs(G - score, i - 1)
        return min(num, dfs(G, i - 1))
    print(dfs(G, D))


main()

Solution (Python):
def main():
    D, G, *pc = map(int, open(0).read().split())
    p = pc[::2]
    c = pc[1::2]
    ans = 1e9 + 7
    
    comp = [c[i] + 100 * (i + 1) * p[i] for i in range(D)]
    
    for b in range(2 ** D):
        num = 0
        pnt = 0
        
        x = None
        
        for i in range(D - 1, -1, -1):
            
            if b >> i & 1:
                num += p[i]
                
                pnt += comp[i]
            elif x is None:
                x = i
        
        
        if x is None or G <= pnt:
            ans = min(ans, num)
        
        elif G < (100 * (x + 1)) * p[x] + pnt:
            ans = min(ans, num - (-(G - pnt) // (100 * (x + 1))))
    print(ans)
    return


main()

Solution (Python):
def main():
    D, G, *pc = map(int, open(0).read().split())
    p = pc[::2]
    c = pc[1::2]
    ans = 1e9 + 7
    
    for b in range(2 ** D):
        num = 0
        pnt = 0
        
        x = None
        
        for i in range(D - 1, -1, -1):
            
            if b >> i & 1:
                num += p[i]
                
                pnt += c[i] + 100 * (i + 1) * p[i]
            elif x is None:
                x = i
        
        
        if x is None or G <= pnt:
            ans = min(ans, num)
        
        elif G < (100 * (x + 1)) * p[x] + pnt:
            ans = min(ans, num - (-(G - pnt) // (100 * (x + 1))))
    print(ans)
    return


main()

Solution (Python):
def main():
    D, G, *pc = map(int, open(0).read().split())
    p = pc[::2]
    c = pc[1::2]
    ans = 1e9 + 7
    
    for b in range(2 ** D):
        num = 0
        pnt = 0
        
        x = None
        
        for i in range(D - 1, -1, -1):
            
            if b >> i & 1:
                num += p[i]
                
                pnt += c[i] + 100 * (i + 1) * p[i]
            elif x is None:
                x = i
        
        
        if x is None or G <= pnt:
            ans = min(ans, num)
        
        elif -(-(G - pnt) // (100 * (x + 1))) < p[x]:
            ans = min(ans, num - (-(G - pnt) // (100 * (x + 1))))
    print(ans)
    return


main()

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

for i in range(0, 2**(D)):
    binary = "{0:0>{1}b}".format(i, D)
    tmpNum = 0
    tmpCount = 0
    for j in range(D):
        if binary[j] == '1':
            tmpCount += nums[j][0]
            tmpNum += nums[j][0] * (j+1) * 100 + nums[j][1]
        else:
            maxZeroIndex = j

    if tmpNum >= G and count > tmpCount:
        count = tmpCount
    else:
        for j in range(nums[maxZeroIndex][0]):
            tmpNum += (maxZeroIndex+1) * 100
            tmpCount += 1
            if tmpNum >= G and count > tmpCount:
                count = tmpCount

print(count)

Solution (Python):


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

def saiki(n,point,ans,last):
    
    if n==D:
        if point>=G:
            lis.append(ans)
        else:
            if (G-point)<=(No[last]-1)*100*(last+1):
                lis.append(ans+(-(-(G-point)//(100*(last+1)))))
            else:
                pass
    else:
        saiki(n+1,point,ans,n)
        saiki(n+1,point+al[n],ans+No[n],last)

No=[]
al=[]
for i in range(D):
    p,c=map(int,input().split())
    No.append(p)
    al.append(p*(i+1)*100+c)



lis=[]
saiki(0,0,0,0)

print(min(lis))

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

problems = [tuple(map(int, input().split())) for _ in range(D)]
ans = 10**10

for mask in range(1 << D):
    point = 0
    cnt = 0
    for i, (p, c) in enumerate(problems):
        if (mask & (1 << i)) > 0:
            cnt += p
            point += 100 * (i + 1) * p + c

    if point >= G:
        ans = min(ans, cnt)
        continue

    for i, (p, c) in enumerate(problems):
        if (mask & (1 << i)) > 0:
            continue
        ness = -(-(G - point) // (100 * (i + 1)))
        if ness <= p:
            ans = min(ans, cnt + ness)

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

ans = 10 ** 9


for i in range(2 ** D):
    score = 0
    time = 0
    maxj = -1
    
    for j in range(D):
    
        if ((i >> j) & 1):
            score += (j + 1) * PC[j][0] * 100 + PC[j][1]
            time += PC[j][0]
        
        
        else:
            maxj = max(maxj,j)
    
    if maxj == -1:
      ans = min(ans, time)
    
    elif score + (maxj + 1) * (PC[maxj][0] - 1) * 100 >= G:
        
        
        time += max(0, math.ceil((G - score) / (maxj + 1) / 100))
        
        ans = min(ans, time)

print(ans)

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

L = []

t = 10 ** 9
m = 0

for i in range(1,D + 1):
  p,c = map(int,input().split())
  s = 0
  pc = []
  for j in range(p):
    s += i * 100
    if j == p - 1:
      s += c
      L.append([j + 1,s])
    if s >= G and j + 1 < t:
      t = j + 1
    pc.append([j + 1,s])
  PC.append(pc)

def recur(problems):
  
  if len(problems) == D:
    ans = 10 ** 9
    score = 0
    times = 0
    
    for j in range(D):
      if problems[j] == 1:
        score += L[j][1]
        times += L[j][0]
    
    if score >= G:
      ans = min(ans,times)
      return ans
    
    
    else:
      remain = G - score
      if remain <= max([L[i][1] for i in range(D) if problems[i] == 0]):
        for k in range(D):
          if problems[k] == 0:
            for l in range(len(PC[k])):
              if remain <= PC[k][l][1] and ans >= PC[k][l][0]:
                ans = PC[k][l][0]
        ans += times
        return ans
      else:
        return 10 ** 9
  
  else:
    
    ret1 = recur(problems + [1])
    
    ret2 = recur(problems + [0])
    
    return min(ret1,ret2)

print(recur([]))

Solution (Python):

def rec(score: int, idx: int) -> int:
    if idx == 0:  
        return 1 << 30

    point, (num, bonus) = idx * 100, A[idx]
    cnt = min(score // point, num)
    cur_score = cnt * point
    if cnt == num:
        cur_score += bonus

    rest = score - cur_score
    if rest > 0:
        cnt += rec(rest, idx - 1)  

    
    return min(cnt, rec(score, idx - 1))


def main():
    global A
    D, G = map(int, input().split())
    A = [(0, 0)] + [tuple(map(int, input().split())) for _ in range(D)]
    ans = rec(G, D)
    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):
import itertools
import math

d, g = map(int, input().split(" "))

all = set()
for x in range(0, d):
    all.add(x)

pl = list()
for i in range(0, d):
    p, c = map(int, input().split(" "))
    pl.append((i, p, c))

ans = 100000000
for n in range(0, d + 1):
    for select in itertools.combinations(pl, n):
        full_sum = 0
        full_count = 0
        full_list = set()

        for fp, fn, fc in select:
            full_sum += (fp + 1) * 100 * fn + fc
            full_count += fn
            full_list.add(fp)
        
        if full_sum >= g:
            ans = min(ans, full_count)
            

        elif len(all - full_list) > 0:
            rest = max(all - full_list)
            rest_n, rest_p, rest_c = pl[rest]

            if g - full_sum <= (rest_n + 1) * 100 * (rest_p - 1):
                ans = min(ans, full_count + math.ceil((g - full_sum) / ((rest_n + 1) * 100)))
                
        

print(ans)

Solution (Python):

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

if G // 100 <= D:
    print(1)
else:
    N = 0
    for i in range(D):
        pc[i].append((i+1)*100*pc[i][0]+pc[i][1])
        N += pc[i][0]
    dp = [[0, [pc[i][0] for i in range(D)]] for j in range(N)]

    for i in range(N):
        for j in reversed(range(D)):
            if i+1 >= pc[j][0]:
                for k in range(1, pc[j][0]+1):
                    if dp[i - k][1][j] == k:
                        if dp[i][0] < dp[i - k][0] + pc[j][1] + dp[i - k][1][j]*100*(j+1):
                            dp[i][0] = dp[i - k][0] + pc[j][1] + \
                                dp[i - k][1][j]*100*(j+1)
                            dp[i][1] = copy.deepcopy(dp[i-k][1])
                            dp[i][1][j] = 0

            if dp[i-1][1][j] > 0:
                if dp[i][0] < dp[i-1][0] + (j+1)*100:
                    dp[i][0] = dp[i-1][0] + (j+1)*100
                    dp[i][1] = copy.deepcopy(dp[i-1][1])
                    dp[i][1][j] -= 1

        if dp[i][0] >= G:
            print(i+1)
            break

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

min_count = 1001
for i in range(2 ** d):
    s = 0
    count = 0
    max_flag = 0
    for j in range(d):
        if (i >> j) & 1:
            s += 100 * (d - j) * pc[d - j - 1][0] + pc[d - j - 1][1]
            count += pc[d - j - 1][0]
        elif max_flag == 0:
            max_flag = d - j

        if s >= g:
            min_count = min(min_count, count)
            s = 0
            count = 0
            break

    for _ in range(pc[max_flag - 1][0]):
        s += 100 * max_flag
        count += 1
        if s >= g:
            min_count = min(min_count, count)
            s = 0
            count = 0
            break

print(min_count)

Solution (Python):
from math import ceil
dg=list(map(int,input().split()))
pc=[]
ans=0
for i in range(dg[0]):
    pc.append(list(map(int,input().split())))
    ans+=pc[-1][0]
pattern=2**dg[0]
for i in range(2**dg[0]):
    for j in range(dg[0]):
        p=bin(pattern+i)[3:]
        tsum=0
        tans=0
        for k in range(dg[0]):
            if k==j:
                pass
            else:
                if p[k]=="0":
                    tsum+=(1+k)*100*pc[k][0]+pc[k][1]
                    tans+=pc[k][0]
        if tsum<dg[1]:
            dtans=min(pc[j][0]-1,ceil((dg[1]-tsum)/((1+j)*100)))
            tsum+=((1+j)*100)*dtans
            tans+=dtans
        if tans<ans and tsum>=dg[1]:
            ans=tans
print(ans)

Solution (Python):
import math
D, G = map(int,input().split())
p = [0] * D
c = [0] * D
for i in range(D):
    p[i], c[i] = map(int, input().split())
ans = 10**10
for i in range(2**D):
    rest = G
    problems = 0
    for j in range(D):
        if i & 2**(D-j-1):
            problems += p[j]
            rest -= p[j] * (j+1) * 100 + c[j]
        if rest <= 0:
            break
    for j in reversed(range(D)):
        if rest <= 0:
            break
        if i & 2**(D-j-1):
            continue
        add_problems = min(p[j] - 1, math.ceil(rest//((j+1)*100)))
        problems += add_problems
        rest  -= add_problems * (j+1) * 100
    if rest <= 0:
        ans = min(ans, problems)
print(ans)

Solution (Python):
import math
D, G = map(int,input().split())
p = [0] * D
c = [0] * D
for i in range(D):
    p[i], c[i] = map(int, input().split())
ans = 10**10
for i in range(2**D):
    rest = G
    problems = 0
    for j in range(D):
        if i & 2**(D-j-1):
            problems += p[j]
            rest -= p[j] * (j+1) * 100 + c[j]
    for j in reversed(range(D)):
        if rest <= 0:
            break
        if i & 2**(D-j-1):
            continue
        add_problems = min(p[j] - 1, math.ceil(rest//((j+1)*100)))
        problems += add_problems
        rest  -= add_problems * (j+1) * 100
    if rest <= 0:
        ans = min(ans, problems)
print(ans)

Solution (Python):
import math

D, G = map(int, input().split())
P = []

for i in range(D):
  p, c = map(int, input().split())
  P.append(((i + 1)*100, p, c))

ans = float("inf")
for i in range(2 ** D):

  score = 0
  count = 0
  maxj = -1

  for j in range(D):
    
    if ((i >> j) & 1):
      val, p, c = P[j]
      score += c + (val * p)
      count += p
    else:
      maxj = max(maxj, j)

  if maxj == -1:
    if score >= G:
      ans = min(ans, count)
  else:
    val, p, c = P[maxj]
    if score + val * (p - 1) >= G:
      s = max(0, math.ceil((G-score) / val ))
      ans = min(ans, count + s)

print(ans)

Solution (Python):
def get_needed_problems(bini_str):
  point = 0
  cnt = 0

  for i in range(D):
    if bini_str[i] == '1':
      cnt += PC[i][0]
      point += PC[i][0]*(i+1)*100 +PC[i][1]
  if point>=G:
    return cnt
  
  for i in range(D-1,-1,-1):
    if bini_str[i] == '0':
      for j in range(1,PC[i][0]):
        cnt += 1
        point += (i+1)*100
        if point>=G:
          return cnt
  return -1 

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):
  bini_str = bin(i)[2:].zfill(D)
  res = get_needed_problems(bini_str)
  if res != -1:
    ans = min(ans,res)
print(ans)

Solution (Python):
D, G = map(int, input().split())
PC = [0] + [list(map(int, input().split())) for _ in range(D)]
def dfs(i, g):
  if i == 0:
    return 1e9
  mc = min(g // (100 * i), PC[i][0])
  s = mc * 100 * i
  if mc == PC[i][0]:
    s += PC[i][1]
  if s < g:
    mc += dfs(i - 1, g - s)
  return min(dfs(i - 1, g), mc)
print(dfs(D, G))

Solution (Python):
import itertools
import math
import os
import sys

import numpy as np

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")

sys.setrecursionlimit(10 ** 9)
INF = float("inf")
IINF = 10 ** 18
MOD = 10 ** 9 + 7



D, G = list(map(int, sys.stdin.buffer.readline().split()))
P, C = list(zip(*[map(int, sys.stdin.buffer.readline().split()) for _ in range(D)]))
P = np.array(P, dtype=int)
C = np.array(C, dtype=int)

scores = P * np.arange(1, D + 1, dtype=int) * 100 + C
ans = INF
for completes in itertools.product([True, False], repeat=D):
    completes = np.where(completes)[0]

    score = scores[completes].sum()
    cnt = P[completes].sum()
    if score >= G:
        ans = min(ans, cnt)
        continue
    for i in range(D):
        if i in completes:
            continue
        rem = math.ceil((G - score) / ((i + 1) * 100))
        if rem < P[i]:
            ans = min(ans, cnt + rem)
print(ans)

Solution (Python):
D, G = map(int, input().split())
Q = []
for i in range(D):
    p, c = map(int, input().split())
    Q.append([p, c,(i+1)*100])
ans = 10**18
for i in range(2**D):
    state = format(i,'0%ib'%(D))
    value = 0
    count = 0
    for s,(p,c,v) in zip(state,Q):
        if s == '1':
            value += p*v + c
            count += p
    if value >= G:
        ans = min(ans,count)
    else:
        for s,(p,c,v) in zip(reversed(state),reversed(Q)):
            if s == '1':
                continue
            if (G-value) > v*(p-1):
                value += v*(p-1)
                count += p-1
            else:
                if (G-value)%v == 0:
                    c = (G-value)//v
                else:
                    c = int((G-value)/v)+1
                value += v*c
                count += c
                ans = min(ans,count)
                break
print(ans)

Solution (Python):
import itertools


def is_achievable(problems_fully_solved, target):
    score = 0
    n_problems_solved = 0
    for problem in problems_fully_solved:
        score += p_n[problem] * 100 * problem + c_n[problem]
        n_problems_solved += p_n[problem]
    if score >= target:
        return True, n_problems_solved
    problem_partially_solved = max(set(range(1, D+1)) - set(problems_fully_solved))
    for _ in range(1, p_n[problem_partially_solved]):
        score += problem_partially_solved * 100
        n_problems_solved += 1
        if score >= target:
            return True, n_problems_solved
    return False, None


D, G = map(int, input().split(" "))
p_n, c_n = [None, ], [None, ]

for i in range(1, D+1):
    p, c = map(int, input().split(" "))
    p_n.append(p)
    c_n.append(c)

answer = 10000
for combination in itertools.product([True, False], repeat=D):
    l = [i+1 for i in range(D) if combination[i]]
    flag, n_problems_solved = is_achievable(l, G)
    if flag:
        if n_problems_solved < answer:
            answer = n_problems_solved
print(answer)

Solution (Python):
D, G = map(int, input().split())
PC = [0] + [list(map(int, input().split())) for _ in range(D)]
def dfs(i, g):
  if i == 0:
    return 1e9
  mc = min(g // (i * 100), PC[i][0])
  s = 100 * i * mc
  if mc == PC[i][0]:
    s += PC[i][1]
  if s < g:
    mc += dfs(i - 1, g - s)
  return min(mc, dfs(i - 1, g))
print(dfs(D, G))

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

s = 0
Q = []
for i, (p, c) in enumerate(PC):
    s += p
    Q.append((i+1, p, c))
    
dp = [-10**18]*(s+1)
dp[0] = 0

for i, p, c in Q:
  for j in range(s, -1, -1): 
    for k in range(1, p+1): 
      if k == p:
        cc = 100*i*k + c
      else:
        cc = 100*i*k
      if j - k >= 0:
        dp[j] = max(dp[j], dp[j - k] + cc)

for i, total in enumerate(dp):
  if total >= G:
    print(i)
    break

Solution (Python):
from itertools import product

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

ans = 10**18
for pair in product(range(2), repeat=D):
    score = 0
    cnt = 0
    for i, solve in enumerate(pair):
        p, c = pc[i]
        if solve:  
            score += (i + 1) * 100 * p + c
            cnt += p

    if score >= G:
        ans = min(ans, cnt)
        continue

    rest = G - score
    plus = 10**9
    for i, solve in enumerate(pair):
        j = 100*(i+1)
        p, _ = pc[i]
        if not solve:
            need = (rest + j - 1) // j
            if need <= p:
                plus = min(plus, need)
    ans = min(ans, cnt + plus)

print(ans)

Solution (Python):
import sys

n, G = map(int, sys.stdin.readline().split())
G //= 100
p = []
t = []
for i in range(1, n+1):
    pi, ci = map(int, sys.stdin.readline().split())
    p.append(pi)
    t.append(i * pi + ci // 100)

def main():
    res = sum(p)
    for i in range(2 ** n - 1):
        s = 0
        cnt = 0
        for j in range(n):
            if i >> j & 1:
                s += t[j]
                cnt += p[j]
            else:
                m = j + 1
        if s < G:
            tmp = (G - s + m - 1) // m
            if tmp < p[m-1]:
                cnt += tmp
            else:
                continue
        res = min(res, cnt)
    
    return res

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

Solution (Python):
import sys
import numpy as np

I = np.array(sys.stdin.read().split(), dtype=np.int64)
n, G = I[:2]
G //= 100
p, c = I[2:].reshape(-1, 2).T
c //= 100

def main():
    v = np.arange(1, n+1)
    t = v * p + c
    combs = np.arange(2 ** n - 1)[:, None] >> np.arange(n) & 1
    res = p.sum()
    for comb in combs:
        s = t[comb == 1].sum()
        cnt = p[comb == 1].sum()
        if s - G < 0:
            m = np.amax(v[comb == 0])
            tmp = (G - s + m - 1) // m
            if tmp < p[m-1]:
                cnt += tmp
            else:
                continue
        res = min(res, cnt)
    return res

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

Solution (Python):
import math, sys
sys.setrecursionlimit(10**7)
d,g = map(int, input().split())
data = []
ans = 10000000
for i in range(1,d+1):
    p, c = map(int, input().split())
    data.append([i*100 , p , c])
def dfs(li):
    if len(li) == d:
        global ans
        total = 0
        candidate = 0
        for i in range(d):
            if li[i]:
                total += data[i][0] * data[i][1] + data[i][2]
                candidate += data[i][1]
        if total >= g:
            ans = min(ans, candidate)
        else:
            max_point = max([data[i] for i in range(d) if not li[i]])
            if max_point[0] * (max_point[1] - 1) + total >= g:
                candidate += math.ceil((g - total) / max_point[0])
                ans = min(ans, candidate)
    else:
        dfs(li + [False])
        dfs(li + [True])
dfs([])
print(ans)

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


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


scores=sorted(scores,key=lambda x:x[0])[::-1]


ans=D*100
for i in range(2**D):
  total=0
  solve=0
  for j in range(D):
    if (i>>j)&1:
      
      total+=scores[j][3]
      solve+=scores[j][1]
  if total>=G:
    if ans>solve:
      ans=solve
    continue
  rest=G-total
  for j in range(D):
    if (i>>j)&1==0:
      point=scores[j][0]
      num=scores[j][1]-1 
      if point*num<rest:
        rest-=point*num
        solve+=num
      else:
        solve+=(rest//point+(rest%point>0))
        rest=0
    if rest<=0 and ans>solve:
      ans=solve
  
print(ans)

Solution (Python):
import itertools


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

ans = float("inf")
for bit in itertools.product((0, 1), repeat=d):
    score = 0
    solve = 0
    rest = set(range(d))

    for i in range(d):
        if bit[i] == 1:
            score += pc[i][0] * (i+1) * 100 + pc[i][1]
            solve += pc[i][0]
            rest.discard(i)

    if score < g:
        problem = max(rest)
        needs = -((-(g - score)) // ((problem+1)*100))
        n = min(pc[problem][0] - 1, needs)
        score += n * (problem+1) * 100
        solve += n
    if score >= g:
        ans = min(ans, solve)
print(ans)

Solution (Python):
d,g = map(int,input().split())
pc = [list(map(int,input().split())) for _ in range(d)]
ans = float("inf")
def bfs(i,solve,sum,n):
  if i == d:
    if sum>=g:
      global ans
      ans = min(ans,solve)
    elif (pc[n][0]-1)*(n+1)*100 >= g-sum:
      if (g-sum) % ((n+1)*100) == 0:
        plus = (g-sum) // ((n+1)*100)
      else:
        plus = (g-sum) // ((n+1)*100) + 1 
      ans = min(ans,solve+plus)
  else:
    bfs(i+1,solve+pc[i][0],sum+pc[i][0]*(i+1)*100+pc[i][1],n)
    bfs(i+1,solve,sum,i)
bfs(0,0,0,0)
print(ans)

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

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

ans = 10**9
for i in range(1<<d):
    ttl = 0
    cnt = 0
    memo = [0 for i in range(d)]
    for j in range(d):
        if (i>>j)&1:
            ttl += li[j][1]+(j+1)*li[j][0]*100
            cnt += li[j][0]
            memo[j] = 1
    
    if ttl < g:
        memo2 = g- ttl
        for j in range(d-1,-1,-1):
            if memo[j] == 0:
                if memo2%(100*(j+1)) == 0:
                    cnt2 = min(memo2//(100*(j+1)),li[j][0]-1)
                    cnt += cnt2
                    ttl += cnt2*(100*(j+1))
                    
                else:
                    cnt2 = min(((memo2//(100*(j+1)))+1),li[j][0]-1)
                    
                    cnt += cnt2
                    ttl += cnt2*(100*(j+1))
                break
    if ttl >= g:
        ans = min(ans,cnt)
"""   
    if ans == cnt:
        print(memo,ttl,111111)
"""   
    

print(ans)

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

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

ans = 10000
for i in range(2 ** D):
    score = 0
    solve = 0
    maxj = -1
    for j in range(D):  
        if ((i >> j) & 1):  
            score += (j+1)*P[j][0]*100+P[j][1]
            solve += P[j][0]
        else:
            maxj = max(maxj, j)

    if maxj == -1:
        if score >= G:
            ans = min(ans, solve)
    elif score+(maxj+1)*(P[maxj][0]-1)*100 >= G:
        solve += max(0, math.ceil((G-score)/(maxj+1)/100))
        ans = min(ans, solve)
    

print(ans)

Solution (Python):
d, g = map(int, input().split())
ps = [0]*d
cs = [0]*d

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

min_count = sum(ps)
for i in range(2**d-1):
  point = 0
  count = 0
  max_other_j = -1
  for j in range(d):
    if (i >> j) & 1:
      point += (j+1)*100*ps[j] + cs[j]
      count += ps[j]
    else:
      max_other_j = max(max_other_j, j)
  if point < g:
    if max_other_j < 0:
      continue
    else:
      if (g - point)%((max_other_j+1)*100) == 0:
        other_count = (g - point)//((max_other_j+1)*100)
      else:
        other_count = (g - point)//((max_other_j+1)*100)+1
      if other_count >= ps[max_other_j]:
        continue
      else:
        count += other_count
  if count <= min_count:
    min_count = count
  
print(min_count)

Solution (Python):
d, g = map(int, input().split())
ps = [0]*d
cs = [0]*d

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

min_count = sum(ps)
for i in range(2**d-1):
  point = 0
  count = 0
  max_other_j = -1
  for j in range(d):
    if (i >> j) & 1:
      point += (j+1)*100*ps[j] + cs[j]
      count += ps[j]
    else:
      max_other_j = max(max_other_j, j)
  if point < g:
    if max_other_j < 0:
      continue
    else:
      if (g - point)%((max_other_j+1)*100) == 0:
        other_count = (g - point)//((max_other_j+1)*100)
      else:
        other_count = (g - point)//((max_other_j+1)*100)+1
      if other_count >= ps[max_other_j]:
        continue
      else:
        count += other_count
  if count <= min_count:
    min_count = count
  
print(min_count)