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):
from itertools import combinations

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

A = []
B = {i for i in range(D)}
for i in range(D+1):
    A += list(combinations(B, i))



ans = []
for ai in A:
    p = 0  
    c = 0  
    for aii in ai:
        p += PC[aii][2]
        c += PC[aii][0]
    if p < G:
        x = B.difference(ai)
        max_x = max(x)
        cnt = 0
        while p < G and cnt < PC[max_x][0]:
            p += (max_x + 1) * 100
            cnt += 1
            c += 1
        if p >= G:
            
            ans.append(c)
    else:
        
        ans.append(c)

print(min(ans))

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

answer = float('inf')

for bit in range(2 ** D):
    score = 0
    count = 0
    remain = set(range(D))
    for i in range(D):
        if (bit >> i) & 1:
            
            score += PC[i][1] + PC[i][0]*100*(i+1)
            count += PC[i][0]
            remain -= {i}
    
    if score < G :
        use = max(remain)
        
        n = min(-(-(G-score)//((use+1)*100)), PC[use][0])
        count += n
        score += n * (use+1) * 100
    if score >= G:
        answer = min(answer, count)

print(answer)

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

def dfs(i, count, score, remain):
    global answer
    if i == D:
        if score < G:
            use = max(remain)
            n = min(-(-(G-score)//((use+1)*100)), PC[use][0])
            score += 100*n*(use+1)
            count += n
        if score >= G:
            answer = min(answer, count)
    else:
        dfs(i+1, count, score, remain)
        dfs(i+1, count+PC[i][0], score+PC[i][0]*100*(i+1) + PC[i][1], remain-{i})

answer = float('inf')
dfs(0, 0, 0, set(range(D)))
print(answer)

Solution (Python):
import sys
from math import ceil
inputs = sys.stdin.readlines()

d, g = map(int, inputs[0].split())
P = list(map(int, map(lambda x: x.split()[0], inputs[1:])))
C = list(map(int, map(lambda x: x.split()[1], inputs[1:])))

ans = float('inf')
for bit in range(1 << d):
    count, total, rest = 0, 0, set(range(1, d+1))
    for i in range(d):
        if bit & (1 << i):
            total += P[i] * (i + 1) * 100 + C[i]
            count += P[i]
            rest.discard(i + 1)

    if total < g:
        use = max(rest)
        n = ceil((g - total) / (use * 100))
        if P[use-1]-1 < n:
            continue
        count += n
        total += n * use * 100
        
    if total >= g:
        ans = min(ans, count)
print(ans)

Solution (Python):
import sys
from math import ceil
inputs = sys.stdin.readlines()

d, g = map(int, inputs[0].split())
P = list(map(int, map(lambda x: x.split()[0], inputs[1:])))
C = list(map(int, map(lambda x: x.split()[1], inputs[1:])))

ans = float('inf')
for bit in range(1 << d):
    count, total, rest = 0, 0, set(range(1, d+1))
    for i in range(d):
        if bit & (1 << i):
            total += P[i] * (i + 1) * 100 + C[i]
            count += P[i]
            rest.discard(i + 1)

    if total < g:
        use = max(rest)
        n = min(P[use-1], ceil((g - total) / (use * 100)))
        count += n
        total += n * use * 100
    if total >= g:
        ans = min(ans, count)
print(ans)

Solution (Python):
d, g = map(int, input().split())
p_and_c = [list(map(int, input().split())) for _ in range(d)]
min_number = 1000
for i in range(2**d):
    score = 0
    number = 0
    p_and_c_copy = p_and_c.copy()
    rest_num = set(range(1, d+1))
    for j in range(d):
        if i & (1 << j):
            number += p_and_c_copy[j-d][0]
            score += p_and_c_copy[j-d][1] + 100 * (j+1) * p_and_c_copy.pop(j-d)[0]
            rest_num.discard(j+1)
    if p_and_c_copy:
        for k in range(p_and_c_copy[-1][0]):
            if score >= g:
                break
            score += 100 * max(rest_num)
            number += 1
        else:
            continue
    min_number = min(min_number, number)
print(min_number)

Solution (Python):
import math

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





point_per_q_including_bonus = [(100*idx + c[idx])/p[idx] for idx in range(D)]

sum_n_solve_list = []

for bit in range(2**D):
    comp_group_flag = []
    for idx in range(D):
        if ((bit>>idx) & 1):
            comp_group_flag.append(1)
        else:
            comp_group_flag.append(0)
    point_per_q = [100*(idx+1) + c[idx]/p[idx] if comp_group_flag[idx] == 1 else 100*(idx+1) for idx in range(D)]
    pointIDX = zip(point_per_q, comp_group_flag, p)
    pointIDX = sorted(pointIDX, reverse = True, key = lambda x: x[0])
    score = 0
    sum_n_solve = 0
    group = 0
    while score < G and group < D:
        if pointIDX[group][1] == 1:
            n_solve = pointIDX[group][2]
            sum_n_solve += n_solve
            score += pointIDX[group][0] * n_solve
            group += 1
        else:
            
            n_solve = min(math.ceil((G-score)/pointIDX[group][0]), pointIDX[group][2]-1)
            sum_n_solve += n_solve
            score += pointIDX[group][0] * n_solve
            group += 1
    if score >= G:
        sum_n_solve_list.append(sum_n_solve)

print(min(sum_n_solve_list))

Solution (Python):
def main():
    D, G = (int(i) for i in input().split())
    pc = [[int(i) for i in input().split()] for j in range(D)]
    ans = 10**6
    for bit in range(1<<D):
        completed = []
        for i in range(D):
            if bit & (1<<i):
                completed.append(i)
        score = 0
        solve = 0
        for c in completed:
            score += 100*(c+1)*pc[c][0] + pc[c][1]
            solve += pc[c][0]
        for i in range(D)[::-1]:
            if i in completed:
                continue
            less = max(G - score,0)
            if 100*(i+1)*pc[i][0] < less:
                break
            from math import ceil
            solve += ceil(less / (100*(i+1)))
            score += 100*(i+1)*solve
        else:
            ans = min(ans, solve)
    print(ans)

if __name__ == '__main__':
    main()

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

ret = float('inf')
for i in range(2 ** D) :
    g = G
    last = 0
    count = 0
    for j in range(D) :
        if i % 2 == 0 :
            last = j
        else :
            g -= pc[j][0] * (j + 1) * 100 + pc[j][1]
            count += pc[j][0]
        i //= 2
    
    if pc[last][0] * (last + 1) * 100 <= g :
        continue
        
    if g <= 0 :
        ret = min(ret, count)
    else :
        count += -(-g // ((last + 1) * 100))
        ret = min(ret, count)
        
print(ret)

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

df = [[df[i][0], i+1, (df[i][1]//100)+(i+1)*df[i][0]] for i in range(d)]
result = 10**9
for i in range(2**d):
    counter = [0, 0, [0]]
    bin_i = format(i, 'b').zfill(d)
    for j in range(1, len(bin_i)+1):
        if bin_i[-j] == '1':
            counter[0] += df[j-1][0]
            counter[1] += df[j-1][2]
        else:
            counter[2].append(j)
    if counter[1] < g:
        j = max(counter[2])
        if g - counter[1] <= df[j-1][0]*j:
            counter[0] -= ((-1)*(g - counter[1]))//j
        else:
            counter[0] = 10**9
    result = min(counter[0], result)
print(result)

Solution (Python):
import math

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

ans = float('inf')
for bit in range(1 << D):
    count = 0
    num = 0
    rest_num = set(range(1, D+1))

    for i in range(D):
        if bit & (1 << i):
            num += P[i] * (i+1) * 100 + C[i]
            count += P[i]
            rest_num.discard(i+1)

    if num < G:
        max_num = max(rest_num)
        n = min(P[max_num-1], math.ceil((G-num)/(max_num*100)))
        count += n
        num += n * max_num * 100

    if num >= G:
        ans = min(ans, count)

print(ans)

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

ans = float("inf")

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

    for i in range(d):
        if bit & (1 << i):
            sum += pc[i][0] * (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):
d,g = map(int,input().split())
probs = []
ans = float('inf')
for i in range(d):
    p,c =map(int,input().split())
    probs.append(((i+1)*100,p,c))

for i in range(2**d):
    count = 0
    score = 0
    yet = []
    for j in range(d):
        if ((i >>j) & 1):
            count +=probs[j][1]
            score +=probs[j][2] +probs[j][0]*probs[j][1]
        else:
            yet.append((probs[j][0],probs[j][1]-1))
    if ans <= count:
        continue
    elif score>=g:
        ans = count
        continue
    yet.sort(reverse=True)
    if score+sum([x*y for x,y in yet]) <g:
        continue
    for point,num in yet:
        solve = min((g - score-0.1)//point +1,num)
        count += solve
        score += solve*point
        if count >= ans:
            break
        if score >=g:
            ans = count
            break
    
print(int(ans))

Solution (Python):
import math


def dfs(sc, i=0, qn=0, used=set()):
    if sc <= 0:
        return qn
    if i == d:
        i -= 1
        while i in used:
            i -= 1
        hanpa = math.ceil(sc / (100 * (i + 1)))
        if hanpa >= pc[i][0]:
            return inf
        return qn + hanpa
    p, c = pc[i]
    zenbu = (i + 1) * 100 * p + c
    used.add(i)
    re1 = dfs(sc - zenbu, i + 1, qn + p, used)
    used.remove(i)
    re2 = dfs(sc, i + 1, qn, used)
    return min(re1, re2)


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

Solution (Python):

import sys

sys_input = sys.stdin.readline

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

n_solved = 10000000000
for i in range(1 << D):
    score_per_combi = 0
    combi = []
    tmp_n_solved = 0

    for j in range(D):
        if (i >> j) & 1:
            p = pc_list[j][0]
            c = pc_list[j][1]
            score_per_combi += (j + 1) * 100 * p + c
            combi.append(j)
            tmp_n_solved += p

    if tmp_n_solved == 0:
        continue
    if score_per_combi < G:
        continue

    
    
    for problem_idx in combi:
        for solved_num in range(pc_list[problem_idx][0]):
            diff = None
            if solved_num == 0:
                c = pc_list[problem_idx][1]
                diff = (problem_idx + 1) * 100 + c
            else:
                diff = (problem_idx + 1) * 100
            score_per_combi -= diff
            tmp_n_solved -= 1

            if score_per_combi < G:
                tmp_n_solved += 1
                score_per_combi += diff
                break
            
            else:
                continue
            
            break

    
    if tmp_n_solved < n_solved:
        n_solved = tmp_n_solved

print(n_solved)

Solution (Python):
"""
https://atcoder.jp/contests/abc104/tasks/abc104_c
"""
D,G=map(int,input().split())
l = [list(map(int, input().split()))  for _ in range(D)]

minP = 10 ** 100
for i in range(2**D):
  point, tmpP = 0,0
  for j in range(D):
    if (i>>j)&1:
      point += 100*l[j][0]*(j+1) + l[j][1]
      tmpP += l[j][0]
  if point>=G:
    minP = min(minP, tmpP)
  else:
    for j in range(D-1,-1,-1):
      if (i>>j)&1:
        continue
      else:
        for _ in range(l[j][0]):
          point += (j+1)*100
          tmpP += 1
          if point>=G:
            break
      if point >= G:
        break
  minP = min(minP, tmpP)
print(minP)

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


def dfs(i, sum, count, remain):
    global answer
    
    if i == D:
        
        if sum < G:
            use = max(remain)
            n = min(PC[use-1][0], -(-(G-sum)//(use*100)))
            count += n
            sum += 100*use*n
        if sum >= G:
            answer = min(answer, count)
    
    else:
        dfs(i+1, sum, count, remain)
        dfs(i+1, sum + 100*(i+1)*PC[i][0] + PC[i][1], count + PC[i][0], remain-{i+1})
        
answer = float('inf')
dfs(0, 0, 0, set(range(1, D+1)))
print(answer)

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 ** 9
for bit in range(2 ** d):
    cnt = 0
    score = 0

    
    for i in range(d - 1, -1, -1):
        if bit >> i & 1 == 1:
            cnt += p[i]
            score += p[i] * (i + 1) * 100 + c[i]
    
    if score >= g:
        ans = min(ans, cnt)
    else:
        for i in range(d - 1, -1, -1):
            if bit >> i & 1 == 1:
                continue
            
            for j in range(p[i]):
                if score >= g:
                    break

                cnt += 1
                score += (i + 1) * 100
            
        if score >= g:
            ans = min(ans, cnt)

print(ans)

Solution (Python):

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


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

ans = float("inf")

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

Solution (Python):
from math import ceil


def log(s):
    
    pass


def output(x):
    print(x, flush=True)


def input_ints():
    return map(int, input().split())


cache = dict()


def solve(goal, count, meta):
    if (goal <= 0):
        return count

    s = frozenset([m[1] for m in meta])
    if s in cache:
        return cache[s]

    min_count = 999999999

    for m in meta:
        meta2 = list(meta)
        meta2.remove(m)
        c = solve(goal - m[3], count + m[0], meta2)
        if c < min_count:
            min_count = c

    for m in reversed(meta):
        if goal - m[0] * m[1] > 0:
            continue
        c = count + ceil(goal / m[1])
        if c < min_count:
            min_count = c
        break

    cache[s] = min_count

    return min_count


def main():
    d, goal = tuple(input_ints())

    meta = list()
    for i in range(d):
        problems, bonus = tuple(input_ints())
        score = (i + 1) * 100
        meta.append((problems, score, bonus, score * problems + bonus))

    count = solve(goal, 0, meta)
    print(count)


main()

Solution (Python):
def main():
    from math import ceil
    D, G = (int(i) for i in input().split())
    pc = [[int(i) for i in input().split()] for j in range(D)]
    ans = float('inf')
    for bit in range(1<<D):
        completed = []
        tmp = 0
        cur = 0
        for i in range(D):
            if bit & (1<<i):
                completed.append(i)
        for c in completed:
            tmp += (100*(c+1)*pc[c][0] + pc[c][1])
            cur += pc[c][0]
        for d in range(D)[::-1]:
            if d in completed:
                continue
            less = ceil((max(G - tmp,0))/(100 * (d+1)))
            if pc[d][0] < less:
                continue
            tmp += 100*(d+1)*less
            cur += less
            break
        if tmp >= G:
            ans = min(ans,cur)
    print(ans)
if __name__ == '__main__':
    main()

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

ans = float("inf")
for i in range(2**D):
    comp_list = [0]*D
    tmp_num = 0
    tmp_score = 0
    for j in range(D):
        if (i >> j) & 1:
            comp_list[j] = 1
            tmp_num += P[j]
            tmp_score += P[j]*(j+1)*100 + C[j]
    if tmp_score >= G:
        if tmp_num < ans:
            ans = tmp_num
    else:
        list_notcomp= [k for k in range(D) if comp_list[k] == 0]
        if len(list_notcomp) != 0:
            if math.ceil((G - tmp_score) / (100*(max(list_notcomp) + 1))) < P[max(list_notcomp)]:
                tmp_num += math.ceil((G - tmp_score) / (100*(max(list_notcomp) + 1)))
                if tmp_num < ans:
                    ans = tmp_num
print(ans)

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




ans = 1001
for i in range(1<<D):
  q = 0
  s = 0
  for j in range(D):
    if (i>>j)&1 == 1:
      q += P[j]
      s += 100*(j+1)*P[j] + C[j]
  
  
  if i == (1<<D)-1 or s >= G:
    ans = min(ans,q)
  
  
  else:
    for k in range(D-1,-1,-1):
      if (i>>k)&1 == 0:
        break
    q1 = 0
    while (s < G and q1 < P[k]-1):
      s += 100*(k+1)
      q1 += 1
    
    if s >= G:
      ans = min(ans,q+q1)
print(ans)

Solution (Python):
D,G=map(int,input().split())
li=[list(map(int,input().split())) for i in range(D)]
min_n=float('inf')
for i in range(2**D):
    s=0
    n=0
    for b in range(D):
        if (i >> b) & 0b1 == 1:
            s += li[b][0] * (b+1) * 100 + li[b][1]
            n += li[b][0]
    if s < G:
        for b in range(D):
            if ~(i >> (D-b-1)) & 0b1 == 1:
                if (D-b)*100 * li[D-b-1][0] < G-s:
                    n = float('inf')
                    break
                else:
                    n += -(-(G-s) // ((D-b)*100))
                    break
    min_n = min(min_n,n)
print(min_n)

Solution (Python):

import sys
input = sys.stdin.readline
sys.setrecursionlimit(2147483647)
INF=float("inf")
MOD=10**9+7



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 = INF
for i in range(1 << D):
    score = 0
    count = 0
    for j in range(D):
        if ((i >> j) & 1):
            score += (j+1)*P[j]*100+C[j]
            count += P[j]
        else:
            basic = j

    remain = G-score
    if remain <= 0:
        ans = min(ans, count)
        continue



    
    if (remain - ( (P[basic]-1)*(basic+1)*100)) > 0:
        
        continue

    p = P[basic]
    while p > 1 and remain > 0:
        remain -= (basic+1)*100
        p -= 1
        count += 1

    if remain <= 0:
        ans = min(ans, count)

print(ans)

Solution (Python):
D,G = map(int,input().split())
pc = [list(map(int,input().split())) for _ in range(D)]
res = 1<<29
for bit in range(1<<D):
  ans = 0
  num = 0
  for j in range(D):
    if bit&(1<<j):
      ans += pc[j][0]*(j+1)*100+pc[j][1]
      num += pc[j][0]
  if ans >=G:
    res = min(num,res)
  else:
    for j in range(D-1,-1,-1):
      if bit&(1<<j):
        continue
      else:
        for i in range(pc[j][0]):
          if ans>=G:
            break
          ans += 100*(j+1)
          num +=1
    res = min(num,res)
print(res)

Solution (Python):
D,G = [int(x) for x in input().split()]
pc = []
for i in range(D):
  p,c = [int(x) for x in input().split()]
  pc.append([p,c])
res = 1<<29
for bit in range(1<<D):
  ans = 0
  num = 0
  for j in range(D):
    if bit&(1<<j):
      ans += pc[j][0]*(j+1)*100+pc[j][1]
      num += pc[j][0]
  if ans >=G:
    res = min(num,res)
  else:
    for j in range(D-1,-1,-1):
      if bit&(1<<j):
        continue
      else:
        for i in range(pc[j][0]):
          if ans>=G:
            break
          ans += 100*(j+1)
          num +=1
    res = min(num,res)
print(res)

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

min_count = 10 ** 100

for i in range(2 ** D):
    point,cnt = 0, 0
    for j in range(D):
        if i >> j & 1:
            point += pc[j][0] * 100 * (j + 1) + pc[j][1]
            cnt += pc[j][0]
    if point >= G:
        min_count = min(min_count, cnt)
    else:
        for j in range(D-1, -1, -1):
            if i >> j & 1:
                continue
            else:
                for _ in range(pc[j][0]):
                    point += (j+1) * 100
                    cnt += 1
                    if point >= G:
                        break
            if point >= G:
                break
    min_count = min(min_count, cnt)
print(min_count)

Solution (Python):

def rec(score: int, idx: int) -> int:
    if idx == 0:
        return float("inf")
    point, (num, bonus) = idx * 100, A[idx]
    cnt = min(score // point, num)
    cur_score = cnt * point + bonus if cnt == num else cnt * point
    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 sys

input = sys.stdin.readline


class AtCoder:
    def main(self):
        D, G = map(int, input().split())

        p = {}
        c = {}
        for i in range(1, D + 1):
            p[i], c[i] = map(int, input().split())

        ans = 10 * 100
        for i in range(D + 1):
            for comb in itertools.combinations(range(1, D + 1), i):
                score = 0
                ac = 0

                for index in comb:
                    score += c[index] + p[index] * index * 100
                    ac += p[index]

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

                for j in range(1, D + 1)[::-1]:
                    if j in comb:
                        continue

                    if score >= G:
                        break

                    for _ in range(1, p[j]):
                        score += (j * 100)
                        ac += 1

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

                            break
        print(ans)



if __name__ == '__main__':
    AtCoder().main()

Solution (Python):
from collections import defaultdict

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


D, G = getlist()
G = G // 100
bit = []
for i in range(D):
	p, c = getlist()
	bit.append([i + 1, p, c // 100])


ans = float("inf")

for i in range(1 << D):
    score = 0
    lest = []
    val = 0
    for j in range(D):
        if ((i >> j) & 1) == 1:
            lest.extend([bit[j][0]] * bit[j][1])
        else:
        	score += bit[j][0] * bit[j][1] + bit[j][2]
        	val += bit[j][1]
    lest = sorted(lest)
    lest = lest[::-1]
    for j in lest:
    	if score >= G:
    		break
    	else:
    		val += 1
    		score += j
    ans = min(ans, val)

print(ans)

Solution (Python):
d,g = map(int,input().split())
ary = [list(map(int,input().split())) for _ in range(d)]
s = set(i for i in range(d))
ans = float("Inf")
for i in range(2**d):
    a = []
    total,count = 0,0
    for j in range(d):
        if i >> j & 1:
            a.append(j)
    for x in a:
        total += 100*(x+1)*ary[x][0]+ary[x][1]
        count += ary[x][0]
    if total >= g:
        ans = min(ans,count)
        continue
    for y in sorted(s - set(a),reverse=True):
        if total + 100*(y+1)*(ary[y][0]-1) >= g:
            count += -(-(g-total) // (100*(y+1)))
            ans = min(ans,count)
            break
        total += 100*(y+1)*(ary[y][0]-1)
        count += ary[y][0]-1
    if total >= g:
        ans = min(ans,count)
print(ans)

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

    n = len(pc)
    ans = float("inf")

    for i in range(2**n):
        point, cnt = 0, 0
        for j in range(n):
            if (i>>j) & 1:
                point += (j+1)*100*pc[j][0] + pc[j][1]
                cnt += pc[j][0]
        if point >= g:
            ans = min(ans, cnt)
        
        else:
            for j in range(n-1, -1, -1):
                if (i >> j) & 1:
                    continue
                else:
                    for k in range(pc[j][0]):
                        if point >= g:
                            ans = min(ans, cnt)
                            break
                        point += (j+1)*100
                        cnt += 1
    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):
D,G=map(int,input().split())
li=[list(map(int,input().split())) for i in range(D)]
min_n=float('inf')
for i in range(2**D):
    s=0
    n=0
    for b in range(D):
        if (i >> b) & 0b1 == 1:
            s += li[b][0] * (b+1) * 100 + li[b][1]
            n += li[b][0]
    if s < G:
        for b in range(D):
            if ~(i >> (D-b-1)) & 0b1 == 1:
                if (D-b)*100 * li[D-b-1][0] < G-s:
                    n = float('inf')
                    break
                else:
                    n += -(-(G-s) // ((D-b)*100))
                    break
    min_n = min(min_n,n)
print(min_n)

Solution (Python):

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

D, G = map(int, input().split())
PC = [list(map(int, input().split())) for i in range(D)]
ans = float("inf")
    
dfs(0,0,0,set(range(1, D+1)))    
print(ans)

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

p, c = zip(*PC)

min_count = 10**18
for i in range(1<<D):
    h = -1
    point = 0
    count = 0
    for j in range(D):
        if (i>>j)%2:
            point += 100*(j+1)*p[j] + c[j]
            count += p[j]
        else:
            h = j
    if h > -1 and G > point:
        x = -(-(G-point)//(100*(h+1)))
        if x > p[h]:
            continue
        count += x
    min_count = min(min_count, count)

print(min_count)

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

cs = [100*(i+1)*p + c for i, (p, c) in enumerate(pc)]
ans = float("inf")

for i in range(1<<D):
    flag = [False] * D
    score = 0
    num = 0
    for j in range(D):
        
        if (i >> j) & 1:
            flag[j] = True
            score += cs[j]
            num += pc[j][0]

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

    last = -1
    for j in range(D)[::-1]:
        if not flag[j]:
            last = j
            break

    for _ in range(pc[j][0]-1):
        score += 100*(j+1)
        num += 1
        if score >= G:
            ans = min(ans, num)
            break

print(ans)

Solution (Python):
'''
1.全完する問題をbit全探索で選ぶ
2.残った問題に対して、1問辺り点が高い順に解いてく
'''

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

n=len(PC)
ans=float('inf')
for i in range(2**n):
  point,cnt=0,0
  for j in range(n): 
    if i>>j & 1:
      point+=(j+1)*100*PC[j][0] + PC[j][1]
      cnt+=PC[j][0]
  if point>=g:
    ans=min(ans,cnt)
  else:
    for j in range(n-1,-1,-1): 
      if i>>j & 1: 
        continue
      else:
        for k in range(PC[j][0]):
          if point>=g:
            ans=min(ans,cnt)
            break
          point+=(j+1)*100
          cnt+=1
print(ans)

Solution (Python):
D, G = map(int, input().split())
dic = [0]*(D+1)
for i in range(D):
  p, c = map(int, input().split())
  dic[i+1] = (p,c)
ans = 10**9
for i in range(2**D):
  ls = []
  x = i
  v = 0
  count = 0
  for j in range(D):
    if x%2==1:
      ls += [j+1]
    x = x>>1
  for h in ls:
    p, c = dic[h]
    v += p*h*100 + c
    count += p
  if G>v:
    for j in range(D, 0, -1):
      if not j in ls:
        break
    else:
      continue
    m = dic[j][0]
    while m>1:
      v += j*100
      count += 1
      m -= 1
      if v>=G:
        break
    else:
      continue
  if count<ans:
    ans = count
print(ans)