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 sys
import math

input = sys.stdin.readline


def I():
    return int(input())


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


def LI():
    return list(MI())


inf = float("inf")


def main():
    d, g = MI()
    pc = [LI() for _ in range(d)]

    ans = inf
    for bit in range(1 << d):
        c = 0
        score = 0
        for i in range(d):
            if bit & (1 << i):
                c += pc[i][0]
                score += pc[i][0] * 100 * (i + 1) + pc[i][1]

        if score >= g:
            ans = min(ans, c)
        else:
            for i in reversed(range(d)):
                if bit & (1 << i):
                    continue
                res = math.ceil((g - score) / (100 * (i + 1)))
                if res < pc[i][0]:
                    ans = min(ans, c + res)
                break

    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):
import sys
import math

input = sys.stdin.readline


def I():
    return int(input())


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


def LI():
    return list(MI())


inf = float("inf")


def main():
    d, g = MI()
    pc = [LI() for _ in range(d)]

    ans = inf
    for bit in range(2 << d):
        c = 0
        score = 0
        for i in range(d):
            if bit & (1 << i):
                c += pc[i][0]
                score += pc[i][0] * 100 * (i + 1) + pc[i][1]

        if score >= g:
            ans = min(ans, c)
        else:
            for i in reversed(range(d)):
                if bit & (1 << i):
                    continue
                res = math.ceil((g - score) / (100 * (i + 1)))
                if res < pc[i][0]:
                    ans = min(ans, c + res)
                break

    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):

import math


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


"""
Dがちいさいのでビット全探索させたそう
中途半端に色んな得点の問題を解くより、全部解く問題と部分的に解く問題に分かれるはず。
で、部分的に解く問題は、残りの中で一番得点が高い物を選ぶのがよい。
で、それを必要な分（あるいは全部-1）解いて得られる点がGを超えていれば、答えの候補になる
候補の中から最小のを選んで終わり
"""

ans = []
for bit in range(1 << D):
    point = 0
    cnt = 0
    for i in range(D):
        if bit & (1 << i):
            point += 100*(1+i)*PC[i][0] + PC[i][1]
            cnt += PC[i][0] 

    idx = -1
    for i in range(D):
        if not bit & (1 << i):
            idx = i

    if idx == -1:
        ans.append(cnt)
    else:
        rem = max(0, G - point)
        if rem == 0:
            ans.append(cnt)
        else:
            extr_cnt = math.ceil(rem / (100*(idx+1)))
            if extr_cnt <= PC[idx][0]-1:
                ans.append(cnt+extr_cnt)


print(min(ans))

Solution (Python):
from math import ceil
d,g = map(int,input().split())
point = [list(map(int,input().split())) for _ in range(d)]
ans = 10**18
for i in range(2**d):
  l = []
  cnt = 0
  s = 0
  for j in range(d):
    if i >> j & 1:
      cnt += point[j][0]
      s += point[j][0]*100*(j+1) + point[j][1]
    else:
      l.append(j)
  if s >= g:
    ans = min(ans,cnt)
    continue
  for j in l:
    if g-s > 100*(j+1)*(point[j][0]-1):
      continue
    else:
      ans = min(ans,cnt+ceil((g-s)/(100*(j+1))))
print(ans)

Solution (Python):
def rec(i, g, count, rem):
    global ans
    if i == 0:
        
        if g < G:
            
            use = max(rem)
            c = min(pc[use-1][0], -(-(G-g) // (use*100)))
            count += c
            g += use*100 * c
            
            
        if g >= G:
            ans = min(ans, count)
            
    else:
        
        rec(i-1, g, count, rem)
        
        rem[i] = 0
        rec(i-1, g+i*100*pc[i-1][0]+pc[i-1][1], count+pc[i-1][0], rem)
        rem[i] = i


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

rem = [i for i in range(D+1)]
ans = float("inf")

rec(D, 0, 0, rem)

print(ans)

Solution (Python):
def rec(i, g, count, rem):
    global ans
    if i == D:
        
        if g < G:
            
            use = max(rem)
            c = min(pc[use-1][0], -(-(G-g) // (use*100)))
            count += c
            g += use*100 * c
            
        if g >= G:
            ans = min(ans, count)
    else:
        
        rec(i+1, g, count, rem)
        
        rec(i+1, g+(i+1)*100*pc[i][0]+pc[i][1], count+pc[i][0], rem-{i+1})


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

rem = set(range(1, D+1))
ans = float("inf")

rec(0, 0, 0, rem)

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):
import sys
import math


def input():
    return sys.stdin.readline().strip()


sys.setrecursionlimit(20000000)

MOD = 10 ** 9 + 7
INF = float("inf")


def main():
    D, G = map(int, input().split())
    problems = [list(map(int, input().split())) for _ in range(D)]
    answer = INF
    for i in range(2 ** D):
        ans = 0
        point = 0
        for j in range(D):
            if (i >> j) & 1:
                point += problems[j][0] * 100 * (j + 1) + problems[j][1]
                ans += problems[j][0]
        j = D - 1

        while point < G and j >= 0:
            if not (i >> j) & 1:
                p = math.ceil((G - point) / (100 * (j + 1)))
                if problems[j][0] >= p:
                    point += p * 100 * (j + 1)
                    ans += p
                    j = 0
                else:
                    j = 0
            j -= 1
        if answer > ans and point >= G:
            answer = ans
    print(answer)


if __name__ == "__main__":
    main()

Solution (Python):
import sys
from itertools import permutations

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


def input():
    return sys.stdin.readline().strip()


def main():
    D, G = map(int, input().split())
    PC = [(0, 0, 0)]
    for i in range(1, D + 1):
        p, c = map(int, input().split())
        PC.append((i, p, c))
    perms = permutations(range(1, D + 1))

    ans = INF
    for p in perms:
        tmp = 0
        cnt = 0
        for idx in p:
            i, p, c = PC[idx]
            if tmp + 100 * i * p >= G:
                cnt += (G - tmp + 100 * i - 1) // (100 * i)
                break
            elif tmp + 100 * i * p + c >= G:
                cnt += p
                break
            else:
                tmp += 100 * i * p + c
                cnt += p

        if cnt < ans:
            ans = cnt

    print(ans)


if __name__ == "__main__":
    main()

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

import math

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

ans = float("inf")

for i in range(2 ** D):
    total = 0
    num = 0
    idx = []
    for k in range(D):
        if i >> k & 1 == 1:
            idx.append(k)
    
    for j in idx:
        d = data[j]
        total += d[0] * d[1] + d[2]
        num += d[1]
    
    if total >= G:
        ans = min(ans, num)
    else:
        for j in set(range(D)) - set(idx):
            d = data[j]
            if total + d[0] * (d[1] - 1) >= G:
                num += math.ceil((G - total) / d[0])
                ans = min(ans, num)
                continue
            else:
                total += + d[0] * (d[1] - 1)
                num += d[1] - 1
print(ans)

Solution (Python):

 
d, g = map(int, input().split())
pc = []
 
for i in range(d):
  pc.append(list(map(int,input().split())))
 
ans = float("inf")
 

 
for i in range(2**d):
    count = 0 
    sum = 0
    nokori = set(range(1, d + 1)) 
 
    for j in range(d):
        if (i>>j)&1:
            sum += pc[j][0] * (j + 1) * 100 + pc[j][1] 
            count += pc[j][0]
            nokori.discard(j + 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().strip().split())
pc=[]
for _ in range(D):
    pc.append(list(map(int,input().strip().split())))
    
min_num=0
for i in range(D):
    min_num+=pc[i][0]

def dfs(l,D,G):
    global min_num
    score=0
    num=0
    if len(l)==D:
        for n in range(len(l)):
            if l[n]==1:
                score+=pc[n][0]*100*(n+1)+pc[n][1]
                num+=pc[n][0]
        if score>=G:
            min_num=min(min_num,num)
        else:
            for n in reversed(range(len(l))):
                if l[n]==0:
                    i=0
                    while i<=pc[n][0]-1 and score<G:
                        score+=100*(n+1)
                        num+=1
                        i+=1
                    if score>=G:
                        break
            min_num=min(min_num,num)
        return
    else:
        for n in range(2):
            l.append(n)
            dfs(l,D,G)
            l.pop()
dfs([],D,G)
print(min_num)

Solution (Python):
def q3():
    import itertools
    l1 = input().split()
    D = int(l1[0])  
    G = int(l1[1])  

    P = []  
    C = []  
    for i in range(D):
        l = input().split()
        P.append(int(l[0]))
        C.append(int(l[1]))

    
    for i in range(D):
        li = list(itertools.product([1, 0], repeat=D))

    ans = float('INF')
    for e in li:
        tmp_sum = 0  
        tmp_ans = 0  

        
        for i, flag in enumerate(e):
            tmp_sum += (P[i]*(i+1)*100 + C[i]) * flag
            tmp_ans += P[i]*flag

        

        
        if tmp_sum >= G:
            ans = min(ans, tmp_ans)  
            continue

        for i in range(D-1, -1, -1):
            if e[i] == 1:
                continue
            for _ in range(0, P[i]):
                tmp_sum += (i+1)*100
                tmp_ans += 1
                

                if tmp_sum >= G:
                    ans = min(ans, tmp_ans)  
                    break
            if tmp_sum >= G:
                break

    return ans

if __name__ == "__main__":
    print(q3())

Solution (Python):
import itertools
D, G = map(int, input().split())
pc = [list(map(int, input().split())) for _ in range(D)]
bit = itertools.product([0, 1], repeat=D)
ans = 1000
for bi in bit:
    cnt = 0
    score = 0
    nokori = []
    for i in range(D):
        if bi[i] == 0:
            nokori.append([pc[i][0], (i+1)*100])
            continue
        score += pc[i][1] + 100*(i+1)*(pc[i][0])
        cnt += pc[i][0]
    if score >= G:
        ans = min(ans, cnt)
    else:
        for num, point in reversed(nokori):
            for j in range(1, num):
                cnt += 1
                score += point
                if score >= G:
                    ans = min(ans, cnt)
                    break
            else:
                continue
            break
print(ans)

Solution (Python):
'''

1 <= D <= 10
1 ≤  pi≤100
100≤ ci≤10**6
100≤ G

＜回答・解説より＞
以下のような選択のみを考慮しても最適解はそれらの選択に含まれます。
• 中途半端に解く配点は 1 種類以下であり、それ以外の配点は完全に解くかまったく解かない。
• 中途半端に解く配点があるなら、それは完全に解く配点以外の配点の中で最も高い配点である。

このような選択をすべて列挙するには、D 種類の配点それぞれに対してその配点を完全に解くか否かを決定し、
必要であれば残りの配点のうち最も高いものを中途半端に解く配点とすればよいです
（中途半端に解く配点の問題を 1 問除きすべて解いても目標点に達しない場合は、完全に解く配点の選択が不適切であったとして無視します）。

↓
考え方
「ある点数帯の問題を全部解く」を全パターン試す。
・目標点数を満たす、最小の問題数（の組み合わせ）をAとする
・Aの次に目標点数に近い（が満たさない、組み合わせ）をBとする。
　→Bに、「完全に解く配点以外の配点の中で最も高い配点」の問題を条件を満たすまで解いて問題数を確認する。B'とする
　　→AとB'のうち、解く問題数が少ないほうを回答とする。

'''





import sys
input = sys.stdin.readline

inf = float('inf')
is_debug = False

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

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

def main():
    '''メイン処理'''
    
    points_list = []
    for i in range(2**d):
        
        solve_list = [0] * d
        
        bin_str = bin(i)[2:].zfill(d)
        
        for j in range(d):
            if bin_str[j] == '1':
                solve_list[j] = 1

        solve_num = 0
        points = 0
        for k in range(d):
            if solve_list[k] == 1:
                q_num, bonus = M[k]
                solve_num += q_num
                points += (q_num*(k+1)*100) + bonus
        points_list.append([solve_num, points, solve_list])
    
    if is_debug:
        print(sorted(points_list))
    
    min_solve_num = inf
    for index, [solve_num, points, solve_list] in enumerate(sorted(points_list, reverse=True)):
        next_loop = False
        if points >= g and solve_num < min_solve_num:
            
            a_ans = [solve_num, points]
            min_solve_num = solve_num
        elif points < g and solve_num < min_solve_num:
            
            
            for i in range(len(solve_list)-1,-1,-1):
                if solve_list[i] == 0:
                    q_num = M[i][0]
                    for _ in range(q_num):
                        points += (i+1)*100
                        solve_num += 1
                        if solve_num >= min_solve_num:
                            next_loop = True
                        elif points >= g and solve_num < min_solve_num:
                            min_solve_num = solve_num 
                        
                        if next_loop:
                            break
                if next_loop:
                    break

    if is_debug:
        print(a_ans)
    print(min_solve_num)


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")
tmp=0
for i in range(2**d):
    count=0
    s=0
    nokori=set(range(1,d+1))
    for k in range(d):
        if i &(1<<k):
            s+=pc[k][0]*(k+1)*100+pc[k][1]
            count+=pc[k][0]
            nokori.discard(k+1)
    if s<g:
        use=max(nokori)
        n=min(pc[use-1][0],-(-(g-s)//(use*100)))
        count+=n
        s+=n*use*100
    if s>=g:
        ans=min(ans,count)
print(ans)

Solution (Python):
D, G = map(int,input().split())
p,C = [],[]
for i in range(D):
    p_,c_ = map(int,input().split())
    p.append(p_)
    C.append(c_)
ans = float('inf')
 
for i in range(2**D):
    s, k = 0, 0
 
    for j in range(D):
        if (i>>j) & 1:
            s += p[j]*(j+1)*100 + C[j] 
            k += p[j]
    if s >= G:
        ans = min(ans, k)
    else:
        for l in range(D-1, -1, -1):
            if (i>>l) & 1 == 0: 
                if s+(l+1)*100*p[l]<G:
                    break
                else:
                    rem = G - s
                    k += -(-rem//((l+1)*100))
                    ans = min(ans, k)
print(ans)

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

ans = float("inf")

for bit in range(1<<d):
  sum=0
  count=0
  nokori=set(range(1,d+1))
  for i in range(d):
    if bit&(1<<i):
      sum += p[i]*100*(i+1)+c[i]
      count+= p[i]
      nokori.discard(i + 1)
  if sum<g:
    a=g-sum
    num=max(nokori)
    n=min(p[num-1],-(-a//(num*100)))
    count+=n
    sum+=n*num*100
  if sum>=g:
    ans=min(ans,count)
    
print(ans)

Solution (Python):
def main():
    D,G = [int(x) for x in input().split()]
    min_cnt = 0
    bonus = []
    for i in range(D):
        p,c = [int(x) for x in input().split()]
        bonus.append((p,c))
        min_cnt += p
    
    

    for bit in range(1<<D):
        score = 0
        cnt = 0
        for i,(p,c) in enumerate(bonus):
            if (1<<i) & bit:
                score += 100*(i+1)*p+c
                cnt += p
        
        if score >= G:
            min_cnt = min(min_cnt, cnt)
        else:
            for i in reversed(range(0,D)):
                if (1<<i) & bit:
                    continue
                pi,ci = bonus[i]
                for j in range(pi-1):
                    score += 100*(i+1)
                    cnt += 1
                    
                    if score >= G:
                        
                        min_cnt = min(min_cnt, cnt)
                        break
    print(min_cnt)

if __name__ == '__main__':
    main()

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

for bit in range(1<<d):
  sum=0
  count=0
  nokori=set(range(1,d+1))
  for i in range(d):
    if bit&(1<<i):
      sum += pc[i][0]*100*(i+1)+pc[i][1]
      count+= pc[i][0]
      nokori.discard(i + 1)
  if sum<g:
    a=g-sum
    num=max(nokori)
    n=min(pc[num-1][0],-(-a//(num*100)))
    count+=n
    sum+=n*num*100
  if sum>=g:
    ans=min(ans,count)
print(ans)

Solution (Python):
d, g = map(int, input().split())
A, B = [], []
for _ in range(d):
    a, b = map(int, input().split())
    A.append(a)
    B.append(b)
ans = float('inf')

for i in range(2**d):
    s, k = 0, 0 

    for j in range(d):
        if (i>>j)&1:
            s+=A[j]*(j+1)*100 + B[j] 
            k+=A[j] 
    if s >= g:
        ans = min(ans, k)
    else:
        for l in range(d-1, -1, -1):
            if (i>>l)&1 == 0: 
                if s+(l+1)*100*A[l]<g: 
                    s+=(l+1)*100*A[l]
                    k+=A[l]
                else:
                    rem = g-s 
                    k += -(-rem//(l+1)//100)
                    ans = min(ans, k)
print(ans)

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

ptns = []
for i in range(2 ** d):
    ptn = []
    for j in range(d):
        if ((i >> j) & 1):
            ptn.append(j)
    ptns.append(ptn)

ret = 10 ** 10

for item in ptns:
    cnt = 0
    pnt = 0
    for val in item:
        cnt += pc_ls[val][0]
        pnt += (100 * (val + 1)) * pc_ls[val][0] + pc_ls[val][1]
    left = g - pnt
    if left <= 0:
        ret = min(ret, cnt)
    else:
        for i in range(1, d + 1):
            if (d - i) in item:
                continue
            else:
                max_val = (100 * (d - i + 1)) * pc_ls[-i][0]
                if max_val < left:
                    cnt += pc_ls[-i][0]
                    left -= max_val
                else:
                    cnt += (left + 100 * (d - i + 1) -
                            1) // (100 * (d - i + 1))
                    break
        ret = min(ret, cnt)

print(ret)

Solution (Python):
from math import ceil

d, g = [int(x) for x in input().split()]

c_list = []
ans = 0
for i in range(d):
    p, c = [int(x) for x in input().split()]
    c_list.append((100 * (i + 1) * p + c, p))
    ans += p
c_list = list(reversed(c_list))

for i in range(2 ** d):
    s = 0
    temp_ans = 0
    flag = True
    for j in range(d):
        temp = (i >> j) & 1
        if temp == 1:
            s += c_list[j][0]
            temp_ans += c_list[j][1]
            if s >= g:
                break
        elif flag:
            k = j
            flag = False
    else:
        temp_s = (d - k) * 100
        temp = ceil((g - s) / temp_s)
        if  temp < c_list[k][1]:
            s += temp_s * temp
            temp_ans += temp
    if s >= g and temp_ans < ans:
        ans = temp_ans
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):
d , g = map(int, input().split())
pc = [list(map(int, input().split()))for i in range(d)]
x=[]
y=[0]*d
ac=[0]*d
for i in range(d):
    ac[i]=pc[i][0]*(i+1)*100+pc[i][1]

def dfs(n,m,y,now):
    if now==n:
        z=y.copy()
        x.append(z)
        return
    for i in range(m):
        y[now]=i
        dfs(n,m,y,now+1)
dfs(d,3,y,0)
mi = 1000
for i in x:
    sum = 0
    cost = 0
    stock = []
    sum2 = 0
    cost2 = 0
    for j in range(d):
        if i[j]==1:
            sum+=ac[j]
            cost+=pc[j][0]
            sum2+=ac[j]
            cost2+=pc[j][0]
        if i[j]==2:
            stock+=[(j+1)*100]*pc[j][0]
            sum2+=pc[j][0]*(j+1)*100
            cost2+=pc[j][0]
    if sum2<g:
        continue
    stock.sort()
    if abs(sum2-g)>abs(sum-g):
        while sum<g and stock:
            sum+=stock.pop()
            cost+=1
        if sum>=g:
            mi=min(mi,cost)
    else:
        while sum2>g and stock:
            sum2-=stock.pop()
            cost2-=1
        cost+=1
        mi=min(mi,cost2)

print(mi)

Solution (Python):
d,g=map(int,input().split())
A,B=[],[]
for i in range(d):
    a,b=map(int,input().split())
    A.append(a)
    B.append(b)
ans=float("inf")
for i in range(2**d):
    s,k=0,0
    for j in range(d):
        if (i>>j)&1:
            s+=A[j]*(j+1)*100+B[j]
            k+=A[j]
    if s>=g:
        ans=min(ans,k)  
    else:
        for l in range(d-1,-1,-1):
            if (i>>l)&1==0:
                if s+(l+1)*100*A[l]<g:
                    s+=(l+1)*100*A[l]
                    k+=A[l]
                else:
                    rem=g-s
                    k+=-(-rem//(l+1)//100)
                    ans=min(ans,k)
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())

point =[i*100 for i in range(1, d+1)]
ans = float("inf")

for i in range(1<<d):
  score = 0
  cnt = 0
  for j in range(d):
    if i>>j &1:
      cnt += p[j]
      score += point[j]*p[j] + c[j]
  if score >= g:
    ans = min(ans, cnt)
    continue
  for j in range(d)[::-1]:
    if i >> j &1:
      continue
    x = min(math.ceil((g-score)/point[j]), p[j]-1)
    cnt += x
    score += point[j]*x
    if score >= g:
      ans =min(ans, cnt)
      break
print(ans)

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

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

res = float('inf')

for i in range(2**D):
  score, solved = 0, 0
  all_solved = []

  for j in range(D):
    if (i>>j)&1:
      score += 100*(j+1)*p[j] + c[j]
      solved += p[j]
      all_solved.append(j)
      if score >= G: break

  if score < G:
    for k in range(D-1, -1, -1):
      if k not in all_solved:
        for num in range(p[k]):
          score += 100*(k+1)
          solved += 1
          if score >= G: break
        if score >= G: break
        score += c[k]

  if score >= G:
    res = min(res, solved)

print(res)

Solution (Python):


D,G = list(map(int, input().rstrip().split()))
pc_list = [list(map(int, input().rstrip().split())) for i in range(D)]


bit = 1 << D
min_cnt = 10*100

for b in range(bit):
    score = 0
    cnt = 0
    
    for i in range(D):
        if b & (1 << i):
            p = pc_list[i][0]
            c = pc_list[i][1]
            
            score += p * (100*(i+1)) + c
            cnt += p
    
    if score >= G:
        min_cnt = min(min_cnt, cnt)
    
    else:
        flag = False
        
        for i in reversed(range(len(pc_list))):
            if flag:
                break
            
            if b & (1 << i):
                continue
            
            p = pc_list[i][0]
            
            for j in range(p-1):
                score += 100*(i+1)
                cnt += 1
                
                if score >= G:
                    min_cnt = min(min_cnt, cnt)
                    flag = True
                    break

print(min_cnt)

Solution (Python):
import math
a,b=map(int,input().split())
List=[list(map(int,input().split())) for i in range(a)]
ans=10000000000000
for i in range(2**a):
  s=0
  c=0
  t=True
  x=0
  y=0
  for j in range(a):
    if (i>>j) & 1:
      s+=(a-j)*100*List[a-1-j][0]+List[a-1-j][1]
      c+=List[a-1-j][0]
    else:
      if t:
        x=(a-j)*100
        y=List[a-1-j][0]
        t=False
  if b<=s:
    if ans>c:
      ans=c
  else:
    if math.ceil((b-s)/x)<=y:
      c+=math.ceil((b-s)/x)
      if ans>c:
        ans=c
print(ans)

Solution (Python):

import sys
import math

def solve(D: int, G: int, p: "List[int]", c: "List[int]"):
    ans = 1e9
    for bit in range(2 ** D):
        sum = 0
        rest_max = -1
        num = 0

        for i in range(D):
            if bit & 1 << i:
                sum += (i + 1) * 100 * p[i] + c[i]
                num += p[i]
            else:
                rest_max = i
        
        if sum < G:
            remain = G - sum
            s1 = 100 * (rest_max + 1)
            need = math.ceil(remain / s1)
            if need >= p[rest_max]:
                continue
            num += need
        ans = min(ans, num)

    print(ans)
    return



def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    D = int(next(tokens))  
    G = int(next(tokens))  
    p = [int()] * (D)  
    c = [int()] * (D)  
    for i in range(D):
        p[i] = int(next(tokens))
        c[i] = int(next(tokens))
    solve(D, G, p, c)

if __name__ == '__main__':
    main()

Solution (Python):

import sys


def solve(D: int, G: int, p: "List[int]", c: "List[int]"):
    ans = 1e9
    for bit in range(2 ** D):
        sum = 0
        rest_max = -1
        num = 0

        for i in range(D):
            if bit & 1 << i:
                sum += (i + 1) * 100 * p[i] + c[i]
                num += p[i]
            else:
                rest_max = i
        
        if sum < G:
            
            
            s1 = 100 * (rest_max + 1)
            need = int((G - sum + s1 - 1) / s1)
            if need >= p[rest_max]:
                continue
            num += need
        ans = min(ans, num)

    print(ans)
    return



def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    D = int(next(tokens))  
    G = int(next(tokens))  
    p = [int()] * (D)  
    c = [int()] * (D)  
    for i in range(D):
        p[i] = int(next(tokens))
        c[i] = int(next(tokens))
    solve(D, G, p, c)

if __name__ == '__main__':
    main()

Solution (Python):
d,g = map(int,input().split())
p = [0]*d
c = [0]*d
for i in range(d): p[i],c[i] = map(int,input().split())
point = [i*100 for i in range(1,d+1)]
ans = float("inf")

for i in range(1<<d):
    score = 0
    cnt = 0
    for j in range(d):
        if i>>j & 1:
            cnt += p[j]
            score += point[j] * p[j] + c[j]
    if score >= g:
        ans = min(cnt,ans)
        continue
    for j in range(d)[::-1]:
        if i>>j & 1: continue
        x = min((g-score+point[j]-1)//point[j],p[j]-1)
        cnt += x
        score += point[j]*x
        if score >= g:
            ans = min(ans, cnt)
            break
print(ans)