CodeEff/ECCO huggingface dataset:
# Original solution
d, g = list(map(int, input().split()))
pc = [list(map(int, input().split())) for i in range(d)]
ans = float("inf")
for bit in range(1 << d):
    count = 0
    sum = 0
    nokori = set(range(1, d + 1))
    for i in range(d):
        if bit & (1 << i):
            sum += pc[i][0] * (i + 1) * 100 + pc[i][1]
            count += pc[i][0]
            nokori.discard(i + 1)
    if sum < g:
        use = max(nokori)
        count += min(pc[use - 1][0], -(-(g - sum) // (use * 100)))
        sum += min(pc[use - 1][0], -(-(g - sum) // (use * 100))) * use * 100
    if sum >= g:
        ans = min(ans, count)
print(ans)

# Optimized solution
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)
        return 0
    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 = list(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)
# Original solution
#abc104c all green 
d, g = list(map(int, input().split()))
pc = [list(map(int, input().split())) for _ in range(d)]
all_sum = []
for bit in range(1<<d):
    s = 0
    a = 0
    rest = []
    for i in range(d):
        if bit & (1<<i):
            s += pc[i][0]*100*(i+1) + pc[i][1]
            a += pc[i][0]
        else :
            rest.append(i)
    
    if s >= g :
        all_sum.append(a)
    else :
        k = max(rest)
        diff = g - s
        for j in range(pc[k][0]):
            if j*(k+1)*100 >= diff:
                all_sum.append(a+j)
print((min(all_sum)))

# Optimized solution
def dfs(i, sum, count, rest):
    global ans
    if i == d:
        if sum < g:
            rest_max = max(rest)
            n = min(l[rest_max-1][0], -(-(g-sum)//(rest_max*100)))
            count += n
            sum += n * rest_max * 100
        if sum >= g:
            ans = min(ans, count)
    else :
        dfs(i+1, sum, count, rest) #二分岐のうち解かない選択
        dfs(i+1, sum + l[i][0]*(i+1)*100+l[i][1], count + l[i][0], rest - {i+1}) #解く選択

d, g = list(map(int, input().split()))
l = [list((list(map(int, input().split())))) for _ in range(d)]
ans = float("inf")
dfs(0, 0, 0, set(range(1, d+1)))
print(ans)
# Original solution
D, G = list(map(int, input().split()))
pc = [list(map(int, input().split())) for i in range(D)]
G /= 100
C = 2e3
N = len(pc)
for i in range(2 ** N):
    p = 0
    c = 0
    for j in range(N):
        if i >> j & 1:
            p += pc[j][0] * (j + 1) + pc[j][1] / 100
            c += pc[j][0]
    if p >= G:
        C = min(c, C)
        continue
    for j in range(N-1, -1, -1):
        if not i >> j & 1:
            for k in range(pc[j][0] - 1):
                p += j + 1
                c += 1
                if p >= G:
                    break
        if p >= G:
            break
    if p >= G:
        C = min(c, C)
        continue

print(C)

# Optimized solution
D, G = list(map(int, input().split()))
G = int(G / 100)
pc = [list(map(int, input().split())) for _ in range(D)]

N = 10 ** 9
for bit in range(2 ** D):
    S = 0
    c = 0
    A = True
    a = -1
    for i in range(D - 1, -1, -1):
        if bit & (1 << i):
            S += (i + 1) * pc[i][0] + int(pc[i][1] / 100)
            c += pc[i][0]
        elif A:
            a = i
            A = False
    if a != -1:
        for i in range(1, pc[a][0]):
            if S >= G:
                break
            S += a + 1
            c += 1
    if S >= G:
        N = min(N, c)

print(N)
# Original solution
import math
 
d,g = [int(i) for i in input().split()]
P = []
C = []
for i in range(d):
    p,c = [int(i) for i in input().split()]
    P.append(p)
    C.append(c)

# cnt = 0
# def count():
#     global cnt
#     cnt+=1
#     print(cnt)

def flag(point,P,now):
    if point+100*(now+1)*P >= g: return 1
    else: return 0

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

score()
print(m)

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

# cnt = 0
# def count():
#     global cnt
#     cnt+=1
#     print(cnt)

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

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

score()
print(m)
# Original solution
def main():
    D, G, *pc = list(map(int, open(0).read().split()))
    p = pc[::2]
    c = pc[1::2]
    ans = 1e9 + 7
    # 2 ** D - 1 まで
    for b in range(2 ** D):
        num = 0
        pnt = 0
        # コンプリートしない MAX
        x = None
        # 得点が高い方から
        for i in range(D - 1, -1, -1):
            # i 番目 の フラグ が 立っている
            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)
        # コンプリートしない MAX で 目標の 総合スコア に到達
        elif G < (100 * (x + 1)) * p[x] + pnt:
            ans = min(ans, num - (-(G - pnt) // (100 * (x + 1))))
    print(ans)
    return


main()


# Optimized solution
def main():
    D, G, *pc = list(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)]
    # 2 ** D - 1 まで
    for b in range(2 ** D):
        num = 0
        pnt = 0
        # コンプリートしない MAX
        x = None
        # 得点が高い方から
        for i in range(D - 1, -1, -1):
            # i 番目 の フラグ が 立っている
            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)
        # コンプリートしない MAX で 目標の 総合スコア に到達
        elif G < (100 * (x + 1)) * p[x] + pnt:
            ans = min(ans, num - (-(G - pnt) // (100 * (x + 1))))
    print(ans)
    return


main()
# Original solution
D, G = [int(_) for _ in input().split()]
PC = [[int(_) for _ in input().split()] for i in range(D)]
P = [p for p, c in PC]
C = [c for p, c in PC]

from heapq import *

h = []

heappush(h, (0, 0, (0,)*D))

result = 0

ef = {}

while h:
    t, score, pat = heappop(h)
    # print(t, score, pat)
    if score >= G:
        result = t
        break

    def add(i, pat, d):
        pat1 = list(pat)
        if pat1[i] +d <= P[i]:
            pat1[i] += d
            pat1 = tuple(pat1)
            if not pat1 in ef:
                t1 = t + d
                score1 = score + (i+1)*100*d
                if pat1[i] == P[i]:
                    score1 += C[i]
                ef[pat1] = t
                heappush(h, (t1, score1, pat1))

    for i in range(D-1, -1, -1):
        if pat[i] < P[i]:
            add(i, pat, 1)
            break

    for i in range(D):
        if pat[i] + 1 < P[i]:
            add(i, pat, P[i] - pat[i])

print(result)


# Optimized solution
D, G = [int(_) for _ in input().split()]
PC = [tuple(int(_) for _ in input().split()) for i in range(D)]

from itertools import product

def calc(D, G, PC, es):
    r = 0
    k = None
    result = 0
    for i, e, pc in zip(list(range(D)), es, PC):
        if e:
            r += (i+1) * 100 * pc[0] + pc[1]
            result += pc[0]
        else:
            k = i
    if r >= G:
        return result, r
    if not k is None:
        d = (k+1)*100
        p = PC[k][0]
        if r + d * (p - 1) >= G:
            n = (G - r + d - 1) // d
            result += n
            r += n * d
            return result, r
    return None, None

result = 10**20

for es in product((0, 1), repeat=D):
    r, score = calc(D, G, PC, es)
    #print(D, G, PC, es, r, score)
    if not r is None:
        result = min(result, r)

print(result)
# Original solution
D, G = list(map(int, input().split()))
P, C = [], []

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

ans = float('inf')

for bit in range(2**D):
    is_solve = [ 0 for _ in range(D) ]
    score, solve_num = 0, 0
    # i 番目の bit が立っている => 100(i+1)点をつけられた p_i 問を全完する
    for i in range(D):
        if (bit >> i) & 1:
            score += (100 * (i+1) * P[i] + C[i])
            solve_num += P[i]
            is_solve[i] += P[i]

    for i in range(D-1, -1, -1):
        if score >= G:
            break

        while is_solve[i] < P[i]:
            score += 100*(i+1)
            solve_num += 1
            is_solve[i] += 1
            if score >= G:
                break

    ans = min(ans, solve_num)

print(ans)



# Optimized solution
D, G = list(map(int, input().split()))
P, C = [], []

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

ans = float('inf')

for bit in range(2**D):
    score, solve_num = 0, 0

    for i in range(D):
        if (bit >> i) & 1:
            score += (100 * (i+1) * P[i] + C[i])
            solve_num += P[i]

    for i in range(D-1, -1, -1):
        if score >= G:
            break

        if (bit >> i) & 1:
            continue

        for j in range(P[i]):
            score += 100*(i+1)
            solve_num += 1

            if score >= G:
                break

    ans = min(ans, solve_num)

print(ans)
# Original solution
D, G = list(map(int, input().split()))
problem = []
bonus_score = []
for i in range(D):
    pi, ci = list(map(int, input().split()))
    problem.append(pi)
    bonus_score.append(ci)
total_problem = sum(problem)
dp= [[0 for k in range(total_problem + 1)] for i in range(D+1)]

for i in range(D):
    for k in range(total_problem + 1):
        for j in range(min(problem[i], k) + 1):
            dp[i+1][k] = max(dp[i+1][k], dp[i][k - j] + (i + 1) * 100 * j + (j//problem[i]) * bonus_score[i])
ans = 0
while dp[D][ans] < G:
    ans += 1
print(ans)
            


# Optimized solution
D, G = list(map(int, input().split()))
problem = []
bonus = []
for i in range(D):
    pi, ci = list(map(int, input().split()))
    problem.append(pi)
    bonus.append(ci)
ans = float('inf')
for S in range(1 << D):  # Sは2^Dの元
    score = sum([(problem[j] * 100 * (j + 1) + bonus[j]) * ((S >> j) & 1) for j in range(D)])
    count = sum([problem[j] * ((S >> j) & 1) for j in range(D)])
    if score >= G:
        ans = min(ans,count)
    else:
        for i in range(D):
            if (S >> i) & 1 == 0 and score + problem[i] * 100 * (i + 1) >= G: #Sにiが含まれないとき
                count_2 = count + (G - score + (100 * (i + 1)) - 1) // (100 * (i + 1))
                ans = min(ans, count_2)
print(ans)
# Original solution
difficulties, goal = list(map(int, input().split()))

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

dp = [[0] * 1102 for _ in range(difficulties + 1)]

for d, pc in enumerate(pcs, 1):
    problem, complete = pc

    score = [x*100*d for x in range(problem)] + [problem*100*d+complete] +[0] * 1001

    for i in range(1, 1001):
        for j in range(0, i + 1):
            if i - j > problem:
                dp[d][i] = max(dp[d][i], dp[d - 1][j])
            else:
                dp[d][i] = max(dp[d][i], dp[d-1][j] + score[i-j])

for i, a in enumerate(dp[difficulties]):
    if a >= goal:
        print(i)
        exit()


# Optimized solution
difficulties, goal = list(map(int, input().split()))

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

dp = [[0] * 1102 for _ in range(difficulties + 1)]

total_problem = 0
for d, pc in enumerate(pcs, 1):
    problem, complete = pc
    total_problem += problem

    score = {x: x*100*d for x in range(problem)}
    score[problem] = problem * 100 * d +complete

    for i in range(1, total_problem + 1):
        for j in range(0, i + 1):
            if i - j > problem:
                dp[d][i] = max(dp[d][i], dp[d - 1][j])
            else:
                dp[d][i] = max(dp[d][i], dp[d-1][j] + score[i-j])

for i, a in enumerate(dp[difficulties]):
    if a >= goal:
        print(i)
        exit()
# Original solution
difficulties, goal = list(map(int, input().split()))

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

dp = [[0] * 1102 for _ in range(difficulties + 1)]

total_problem = 0
for d, pc in enumerate(pcs, 1):
    problem, complete = pc
    total_problem += problem

    score = {x: x*100*d for x in range(problem)}
    score[problem] = problem * 100 * d +complete

    for i in range(1, total_problem + 1):
        for j in range(0, i + 1):
            if i - j > problem:
                dp[d][i] = max(dp[d][i], dp[d - 1][j])
            else:
                dp[d][i] = max(dp[d][i], dp[d-1][j] + score[i-j])

for i, a in enumerate(dp[difficulties]):
    if a >= goal:
        print(i)
        exit()


# Optimized solution
difficulties, goal = list(map(int, input().split()))

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

total_problem = 0
new_dp = [0] * 1001

for d, pc in enumerate(pcs, 1):
    dp = new_dp[:]

    problem, complete = pc
    total_problem += problem

    score = {x: x*100*d for x in range(problem)}
    score[problem] = problem * 100 * d +complete

    for i in range(1, total_problem + 1):
        for j in range(0, i + 1):
            if i - j > problem:
                continue
            else:
                new_dp[i] = max(new_dp[i], dp[j] + score[i-j])

for i, a in enumerate(new_dp):
    if a >= goal:
        print(i)
        exit()
# Original solution
from math import ceil

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

ans = float("inf")
for bit in range(1 << D):
    cnt = 0
    sum = 0
    remain = set(range(1,D+1))

    for i in range(D):
        if bit & (1 << i):
            cnt += pc[i][0]
            sum += pc[i][0]*(i+1)*100 + pc[i][1]
            remain.discard(i+1)

    if sum < G:
        use = max(remain)
        n = min(pc[use-1][0], ceil((G-sum)/(use*100)))
        cnt += n
        sum += n*use*100

    if sum >= G:
        ans = min(ans,cnt)

print(ans)

# Optimized solution
def dfs(i, sum, count, nokori):
    global ans
    if i == d:
        # G 点に満たなければ nokori のうち一番大きいものを解く
        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 = list(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)
# Original solution
import sys
import math

input = sys.stdin.readline


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


def MI():
    return list(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(list(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()


# Optimized solution
import sys
import math

input = sys.stdin.readline


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


def MI():
    return list(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(list(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()
# Original solution
D,G=list(map(int,input().split()))
G//=100
p=[0]*D
c=[0]*D

for i in range(D):
    p[i],c[i]=list(map(int,input().split()))
    c[i]//=100

ans=10**10
for bit in range(2**D):
    score=G
    problems=0
    SET=set([i for i in range(D)])

    for g in range(bit):
        if (bit>>g)&1:
            score-=(g+1)*p[g]+c[g]
            problems+=p[g]
            SET.remove(g)
    
    if score<=0:
        ans=min(ans,problems)
    else:
        #SETが空集合になる時は全ての問題を解いた時であり、全ての問題を解けば必ずscoreは負になるので
        #「ValueError: max() arg is an empty sequence」は防げる。
        MAX=max(SET)
        for _ in range(p[MAX]):
            score-=(MAX+1)
            problems+=1
            if score<=0:
                ans=min(ans,problems)    
                break
print(ans)

# Optimized solution
D,G=list(map(int,input().split()))
G//=100
p=[0]*D
c=[0]*D

for i in range(D):
    p[i],c[i]=list(map(int,input().split()))
    c[i]//=100

ans=10**10
for bit in range(2**D):
    score=G
    problems=0
    SET=set([i for i in range(D)])

    for g in range(D):
        if (bit>>g)&1:
            score-=(g+1)*p[g]+c[g]
            problems+=p[g]
            SET.remove(g)
    
    if score<=0:
        ans=min(ans,problems)
    else:
        #SETが空集合になる時は全ての問題を解いた時であり、全ての問題を解けば必ずscoreは負になるので
        #「ValueError: max() arg is an empty sequence」は防げる。
        MAX=max(SET)
        for _ in range(p[MAX]):
            score-=(MAX+1)
            problems+=1
            if score<=0:
                ans=min(ans,problems)    
                break
print(ans)
# Original solution
d,g=list(map(int,input().split()))
g=g//100
p_list=[0]
c_list=[0]
for i in range(d):
    p,c=list(map(int,input().split()))
    p_list.append(p)
    c_list.append(c//100)
dp=[]
for i in range(d+1):
    sub_list=[]
    for j in range(g+1):
        sub_list.append(10**9)
    dp.append(sub_list)
dp[0][0]=0
for i in range(1,d+1):
    for j in range(g+1):
        for k in range(p_list[i]+1):
            if k==p_list[i]:
                if j-i*k-c_list[i]>=0:
                    dp[i][j]=min(dp[i][j],dp[i-1][j-i*k-c_list[i]]+k)
                else:
                    dp[i][j]=min(dp[i][j],dp[i-1][0]+k)
            else:
                if j-i*k>=0:
                    dp[i][j]=min(dp[i][j],dp[i-1][j-i*k]+k)
                else:
                    dp[i][j]=min(dp[i][j],dp[i-1][0]+k)
print((dp[d][g]))


# Optimized solution
d,g=list(map(int,input().split()))
g=g//100
p_list=[]
c_list=[]
s_list=[]
for i in range(d):
    p,c=list(map(int,input().split()))
    c=c//100
    p_list.append(p)
    c_list.append(c)
    s_list.append(p*(i+1)+c)
Min=1000
for i in range(2**d):
    Sum=0
    Num=0
    for j in range(d):
        if (i>>j)&1==1:
            Sum=Sum+s_list[j]
            Num=Num+p_list[j]
        else:
            M=j
    if Sum>=g:
        if Num<Min:
            Min=Num
    else:
        r=((g-Sum)+M)//(M+1)
        if r<=p_list[M]:
            Num=Num+r
            if Num<Min:
                Min=Num
print(Min)
# Original solution
D,G = list(map(int,input().split()))
P = []
C = []
for i in range(D) :
    p,c = list(map(int,input().split()))
    P.append(p)
    C.append(c)
ans = float("inf")
for i in range(1 << D) : # 2**D
    ct = 0 #cost
    score = 0
    for j in range(D) :
        if (i >> j) & 1 : #bit全探索
            score += C[j] #bonus
            score += P[j] * (j+1) * 100 #normal
            ct += P[j] #cost
    for j in range(D-1,-1,-1) : #降順
        if score >= G : 
            break
        if (i >> j) & 1 : #すでに計算された得点帯を除外
            continue
        g = (j+1)*100
        got = (G-score)//g
        score += min(got,P[j])*g
        ct += min(got,P[j])
    ans = min(ans, ct)
print(ans)


# Optimized solution
D,G = list(map(int,input().split()))
L = [list(map(int,input().split())) for i in range(D)]

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