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

s_in = lambda: stdin.readline()[:-1] 
d_in = lambda: int(stdin.readline()) 
ds_in = lambda: list(map(int, stdin.readline().split())) 

D, G = ds_in()

Score = []
for i in range(D):
    p, c = ds_in()
    Score.append([(i+1)*100, p, c])

INF = 10**10

search = []
def SearchMin(search, idx):
    if idx == D:
        score = 0
        num = 0
        res = []
        maxprob = [0, 0, 0]
        for s, i in zip(Score, search):
            num += s[1] * i
            score += (s[0] * s[1] + s[2]) * i
            if i == 0 and s[0] > maxprob[0]:
                maxprob = s.copy()
        if (G > score) and (math.ceil((G - score) / maxprob[0]) <= maxprob[1]):
            return num + max(0, math.ceil((G - score) / maxprob[0]))
        elif G <= score:
            return num
        else:
            return INF

    else:
        s0 = search.copy()
        s0.append(0)
        s1 = search.copy()
        s1.append(1)
        idx += 1
        ans0 = SearchMin(s0, idx)
        ans1 = SearchMin(s1, idx)
        return min(ans0, ans1)

print(SearchMin(search, 0))

Solution (Python):


INF = float('inf')


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


D, G = inpl()
P, C = [], []
for i in range(D):
    p, c = inpl()
    P.append(p)
    C.append(c + 100 * (i + 1) * p)

ans = INF
for i in range(2 ** D):
    point = 0
    cnt = 0
    rest_max = 0
    for shift in range(D):
        if i >> shift & 1:
            cnt += P[shift]
            point += C[shift]
        else:
            rest_max = shift

    if point < G:
        for j in range(P[rest_max]):
            if point >= G:
                break
            cnt += 1
            point += (rest_max + 1) * 100
        else:
            continue

    ans = min(ans, cnt)

print(ans)

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

ans_cnt = 10 ** 20
for i in range(2 ** (D)):
    def make_p(i):
        p = bin(i)[2::]
        while len(p) != D:
            p = "0" + p
        key = D
        for j in range(D - 1, -1, -1):
            if int(p[j]) == 0:
                key = j
                break
        return p, key
    
    p_and_key = make_p(i)
    p = p_and_key[0]
    key = p_and_key[1]
    cnt = 0
    ansP = 0
    for j in range(len(p)):
        if p[j] == "1":
            ansP += pc[j][0] * 100 * (j + 1) + pc[j][1]
            cnt += pc[j][0]
    j = 0
    if int(key) != int(D):
        key = int(key)
        while ansP < G:
            j = int(j)
            if pc[key][0] <= j:
                break
            ansP += 100 * (key + 1)
            cnt += 1
            j += 1
    if ansP >= G:
        ans_cnt = min(ans_cnt, cnt)

print(ans_cnt)

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

a=[]
for j in range(d):
  a.append([(j+1)*100*l[j][0]+l[j][1],l[j][0]])

b=[]
for k in range(2**d):
  b.append(format(k,'0'+str(d)+'b'))

c=[]
for m in range(len(b)):
  e=0;f=0;z=-1
  for n in range(d):
    if b[m][n]=='1':
      e+=a[n][0];f+=a[n][1]
    else:
      z=n+1
  c.append([e,f,z])

p=[]
for x in range(len(c)):
  q=c[x][0];r=c[x][1];s=c[x][2]
  if q>=g:
    p.append(r)
  else:
    for y in range(a[s-1][1]+1):
      q+=s*100;r+=1
      if q>=g:
        p.append(r)
        break

print(min(p))

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

a=[]
for j in range(d):
  a.append([(j+1)*100*l[j][0]+l[j][1],l[j][0]])

b=[]
for k in range(2**d):
  b.append(format(k,'0'+str(d)+'b'))

c=[]
for m in range(len(b)):
  e=0;f=0;z=-1
  for n in range(d):
    if b[m][n]=='1':
      e+=a[n][0]
      f+=a[n][1]
    else:
      z=n+1
  c.append([e,f,z])

p=[]
for x in range(len(c)):
  if c[x][0]>=g:
    p.append(c[x][1])
  else:
    r=c[x][0];s=c[x][1]
    for y in range(a[c[x][2]-1][1]+1):
      r+=c[x][2]*100
      s+=1
      if r>=g:
        p.append(s)
        break

print(min(p))

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

a=[]
for j in range(d):
  b=[]
  b.append((j+1)*100*l[j][0]+l[j][1])
  b.append(l[j][0])
  a.append(b)

c=[]
for k in range(2**d):
  c.append(format(k,'0'+str(d)+'b'))

e=[]
for m in range(len(c)):
  f=0;h=0;z=-1
  for n in range(d):
    if c[m][n]=='1':
      f+=a[n][0]
      h+=a[n][1]
    else:
      z=n+1
  e.append([f,h,z])

p=[]
for x in range(len(e)):
  if e[x][0]>=g:
    p.append(e[x][1])
  else:
    r=e[x][0];s=e[x][1]
    for y in range(a[e[x][2]-1][1]+1):
      r+=e[x][2]*100
      s+=1
      if r>=g:
        p.append(s)
        break

print(min(p))

Solution (Python):


def main():
    d, g = map(int, input().split())
    prob_list = [tuple(map(int, input().split())) for _ in range(d)]
    ans = float('inf')

    for x in range(2 ** d):
        score = 0
        tmp_ans = 0
        bonus_list = []
        for i in range(d):
            if (x >> i) % 2 == 1:
                score += prob_list[i][0] * (i + 1) * 100 + prob_list[i][1]
                tmp_ans += prob_list[i][0]
                bonus_list.append(i)
        if score < g:
            for j in range(d-1, -1, -1):
                if j not in bonus_list:
                    if score + (prob_list[j][0] - 1) * (j + 1) * 100 >= g:
                        tmp_ans += -(-(g - score) // ((j + 1) * 100)) 
                        break
                    else:
                        tmp_ans = float('inf')
        ans = min(ans, tmp_ans)
    print(ans)

if __name__ == '__main__':
    main()

Solution (Python):
import math
n,g = map(int,input().split())
lis = []
sum = []
for i in range(n):
  a,b = map(int,input().split())
  lis.append([a,b])
  sum.append((i+1)*100*a+b)
def ans(x,y):
  if y <= 0:return 10 ** 12
  nu = min(math.ceil(x/(100 * y)),lis[y-1][0])
  num = 100 * y * nu
  if nu == lis[y-1][0]:num += lis[y-1][1]
  if num >= x:cou = nu
  else:cou = nu +ans(x-num,y-1)
  return min(cou,ans(x,y-1))

print(ans(g,n))

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 = sum(P)
for i in range(2**D - 1):
    inSolve = -1
    score_tmp = 0
    solved = 0
    for j in range(D):
        if (i>>j)%2 == 1:
            score_tmp += (j+1)*100*P[j]+C[j]
            solved += P[j]
        else:
            inSolve = max(j,inSolve)
    if score_tmp < G and inSolve != -1:
        if math.ceil((G-score_tmp)/((inSolve+1)*100)) <= P[inSolve]:
            ans = min(ans,solved + math.ceil((G-score_tmp)/((inSolve+1)*100)))
    elif score_tmp >= G:
        ans = min(ans,solved)
print(ans)

Solution (Python):
def max_zero(t, n):
    if n % 2 == 1:
        n = (n-1) / 2
        t += 1
        return(max_zero(t, n))
    else:
        return t


d, g = [int(_) for _ in input().split()]
l = [0] * d
for i in range(d):
    p, c = [int(_) for _ in input().split()]
    all_score = (i+1)*100*p + c
    l[i] = [p, all_score]

n = 2**d
ans = float('inf')
for i in range(n):
    total = 0
    p_total = 0
    st = '0' + str(d) + 'b'
    n_bin = format(i, st)
    for j in range(d):
        if n_bin[j] == '1':
            total += l[j][1]
            p_total += l[j][0]
    if total >= g:
        ans = min(ans, p_total)
    else:
        b = g - total
        y = max_zero(0, i)
        a = d * 100 - 100 * y
        if b % a == 0:
            u = b // a
        else:
            u = (b // a) + 1
        if u <= l[d-1-y][0]-1:
            ans = min(ans, p_total + u)
print(ans)

Solution (Python):

import itertools
import numpy as np



d, g = map(int,input().split())
ls_p = []
ls_c = []
for i in range(d):
    p, c = map(int,input().split())
    ls_p.append(p)
    ls_c.append(c)
ls_p = np.array(ls_p)
min = ls_p.sum()
ls_c = np.array(ls_c)
nums = [0, 1]
ls_isFull = np.array([list(i) for i in itertools.product(nums, repeat=d)])[:-1]
ls_count = ls_isFull * ls_p

w = np.arange(1,d+1) * 100


def get_idx(ls):
    return max(np.where(ls==0)[0])


for i in range(len(ls_count)):
    
    if ls_count[i].sum() >=  min:
        continue
    idx = get_idx(ls_isFull[i])
    for j in range(ls_p[idx]):

        score = ls_count[i].dot(w) + ls_isFull[i].dot(ls_c)
        

        if (score >= g) &  (ls_count[i].sum() < min):
            min = ls_count[i].sum()
            
            continue
        ls_count[i][idx]+=1
print (min)

Solution (Python):

"""
C - All Green
https://beta.atcoder.jp/contests/abc104/tasks/abc104_c

"""
import sys
from sys import stdin
input = stdin.readline


from itertools import combinations
from math import ceil

def solve(D, G, scores):
    def pick_max(comb):
        a = [i*100 for i in range(D, 0, -1)]
        for c in comb:
            a.remove(c)
        return a[0] if a else None


    ans = float('inf')
    points = [100 * p for p in range(1, D+1)]

    for d in range(D+1):
        for comb in combinations(points, d):
            score = 0
            pick = 0
            for p in comb:
                score += (p * scores[p][0]) + scores[p][1]
                pick += scores[p][0]
            if score < G:
                ad = pick_max(comb)
                if ad:
                    n = ceil((G - score) / ad)
                    if n >= scores[ad][0]:
                        pick = float('inf')
                    else:
                        pick += n
                else:
                    pick = float('inf')
            ans = min(ans, pick)
    return ans


def main(args):
    D, G = map(int, input().split())

    scores = {}
    for i in range(1, D+1):
        p, c = map(int, input().split())
        scores[i*100] = [p, c]
    ans = solve(D, G, scores)
    print(ans)


if __name__ == '__main__':
    main(sys.argv[1:])

Solution (Python):
li = lambda: list(map(int,input().split()))

d,g = li()
g //= 100
num,comp = [], []
for _ in range(d):
    a,b = li()
    num.append(a)
    comp.append(b//100)

from itertools import product
mul = product((0, 1), repeat=d)

ans = float('inf')
for m in mul:
    pt = sum(m[i]*comp[i] for i in range(d)) + sum(m[i]*(i+1)*num[i] for i in range(d))
    n = sum(m[i]*num[i] for i in range(d))
    if pt < g:
        if not all(m):
            i = [i for i,j in enumerate(m) if j==0][-1]
        else:
            continue
        if pt + (i+1)*(num[i]-1) < g:
            continue
        n += -((pt-g)//(i+1))
    ans = min(ans,n)
print(ans)

Solution (Python):
import itertools

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

	ptns = list(itertools.product([0, 1], repeat = d))

	ans = 10 ** 10

	for pt in ptns:
		rest = g - sum([((i + 1) * 100 * problems[i][0] + problems[i][1]) * pt[i] for i in range(d)])
		tmp = sum([problems[i][0] * pt[i] for i in range(d)])
		
		if rest > 0:
			if 0 in pt:
				rest_max_idx = d - pt[::-1].index(0) - 1
				
				for i in range(problems[rest_max_idx][0]):
					rest -= (rest_max_idx + 1) * 100
					tmp += 1
					if rest <= 0:
						break

		if rest <= 0:
			ans = min(ans, tmp)

	print(ans)


if __name__ == '__main__':
	main()

Solution (Python):
d,g=map(int,input().split())
plist=[]
clist=[]
for i in range(d):
    p,c=map(int,input().split())
    plist.append(p-1)
    clist.append(c)
def f(pl,goal):
    result=0
    if goal<0:
        return 0
    for i in range(d,0,-1):
        if goal>=pl[i-1]*(i)*100:
            result+=pl[i-1]
            goal-=pl[i-1]*(i)*100
        else:
            if goal%((i)*100)==0:
                result+=goal//((i)*100)
                goal=0
                break
            
                
            result+=goal//((i)*100)+1
            goal=0
            break
    if goal>0:
        return 1000
    return result
blist=[list(str(bin(i)))[2:][-1::-1]for i in range(2**d)]
result=1000
    
for c in blist:
    qlist=plist[:]
    h=g
    ires=0
    for i in range(len(c)):
        if c[i]=='1':
            qlist[i]=0
            h-=clist[i]+(plist[i]+1)*(i+1)*100
            ires+=plist[i]+1
    result=min([result,f(qlist,h)+ires])
print(result)

Solution (Python):

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

G1 = int(G)
G2 = int(G)
taples = []
count = 1e9

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

for bit in range(1 << D):
	
	sumpoint = 0
	solved = 0
	remprob = []
	for i in range(D):
		
		if (bit >> i) & 1:
			
			sumpoint += 100*(i+1)*taples[i][0]+taples[i][1]
			solved += taples[i][0]
		else:
			
			remprob.append(i)
	
	if sumpoint < G:
		maxi = max(remprob)
		for num in range(1, taples[maxi][0]):
			if sumpoint + 100*(maxi+1)*num >= G:
				count = min(count, solved + num)
				break
	else:
		count = min(count, solved)

print(count)

Solution (Python):
from itertools import product


def f(comb, ans, scores):
    score = 0
    problems = 0
    for i, bi in enumerate(comb):
        if bi == 1:
            score += scores[i][1] + scores[i][0] * 100 * (i + 1)
            problems += scores[i][0]

    if score >= g:
        return min(ans, problems)

    else:
        for j in reversed(range(d)):
            if comb[j] == 0:
                for _ in range(1, scores[j][0]):
                    problems += 1
                    score += (j + 1) * 100
                    if score >= g:
                        ans = min(ans, problems)
                        return ans

        return ans


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

scores = []
for _ in range(d):
    pc = list(map(int, input().split()))
    scores.append(pc)

ans = float("inf")
for comb in product((0, 1), repeat=d):
    ans = f(comb, ans, scores)

print(ans)

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

pros = []

for i in range(d):
    pros.append(list(map(int,input().split(" "))))
    pros[i].append(100*(i+1)*pros[i][0]+pros[i][1])

min_p = 1000
for i in range(2**d):
    sum_i,pro_num = 0,0
    i_2 = str(bin(i)[2:])
    for k,j in enumerate(i_2[::-1]):
        if sum_i > g or min_p <=pro_num:
            break
        if j == "1":
            sum_i += pros[k][2]
            pro_num += pros[k][0]
    else:
        if sum_i >= g:
            min_p = min(pro_num,min_p)
        else:
            if pro_num < min_p:
                remain = g - sum_i
                i_3 = i_2.zfill(d)
                for k,j in enumerate(i_3):
                    if j == "0":
                        add = 0
                        while remain > 0 and add < pros[d-1-k][0]:
                            remain -= 100*(d-k)
                            add += 1
                            if remain <= 0:
                                pro_num += add
                                min_p = min(pro_num,min_p)
                                break
                        break
print(min_p)

Solution (Python):
import itertools
from collections import Counter
D, G = map(int, input().split())
P = [list(map(int, input().split())) for i in range(D)]
min_num = 10**8

judge_list = list(itertools.product([0, 1, 2], repeat=D)) 


for judge in judge_list:
    score = 0
    num = 0
    d = Counter() 
    d.update(judge)
    if (d[0] <= 1):
        for i in range(1, len(judge) + 1):
            if score >= G:
                break

            if judge[-i] == 1:
                pass

            if judge[-i] == 2:
                score += P[-i][0] * (D - i + 1) * 100 + P[-i][1]
                num += P[-i][0]

            if (judge[-i] == 0):
                for j in range(P[-i][0]):
                    if score >= G:
                        break
                    score += 100 * (D - i + 1)
                    num += 1
                        
        if score >= G:
            min_num = min(num, min_num)

print(min_num)

Solution (Python):
import itertools
import numpy as np

D, G = [int(x) for x in input().split()]

level = np.arange(1, D + 1)
P = np.ndarray(D, dtype=int)
C = np.ndarray(D, dtype=int)
for i in range(D):
    P[i], C[i] = [int(x) for x in input().split()]

complete_scores = level * 100 * P + C

min_problems = P.sum()
for bits in itertools.product([0, 1], repeat=D):
    bits = np.array(bits)
    score_rest = G - (bits * complete_scores).sum()
    if score_rest <= 0:
        min_problems = min(min_problems, (bits * P).sum())
    else:
        for i in reversed(range(D)):
            n_problems = (score_rest + (level[i] * 100) - 1) // (level[i] * 100)
            if bits[i] == 0 and n_problems < P[i]:
                min_problems = min(min_problems, (bits * P).sum() + n_problems)
                break

print(min_problems)

Solution (Python):
d,g=map(int,input().split())
pc=[list(map(int, input().split())) for _ in range(d)]
t1=[bin(2**d+i)[3::] for i in range(2**d)]
a=[]
for t in t1:
    ta=0
    tb=0
    for i in range(d):
        if t[i]=='1':
            ta+=pc[i][0]
            tb+=100*pc[i][0]*(i+1)+pc[i][1]
    if tb>=g:
        a.append(ta)
    else:
        for i in range(d-1,-1,-1):
            if t[i]=='0':
                if 100*(i+1)*pc[i][0]>=g-tb:
                    if (g-tb)%(100*(i+1))==0:
                        ta+=(g-tb)//(100*(i+1))
                        tb+=100*(i+1)*((g-tb)//(100*(i+1)))
                    else:
                        ta+=(g-tb)//(100*(i+1))+1
                        tb+=100*(i+1)*((g-tb)//(100*(i+1))+1)
                break
        if tb>=g:
            a.append(ta)
print(min(a))

Solution (Python):
from itertools import product
from math import ceil

d ,g = map(int, input().split())
problem = [0]*d
bonus = [0]*d
compscore = [0]*d
for i in range(d):
    problem[i], bonus[i] = map(int, input().split())
    compscore[i] = 100*(i+1)*problem[i] + bonus[i]
ans = 1001



for c in product(range(2), repeat=d):
    score = 0
    solved = 0
    max_of_notcomp = -1

    for i in range(d):
        if c[i] == 1:
            score += compscore[i]
            solved += problem[i]
        else:
            max_of_notcomp = i
    
    if score < g and score + 100*(max_of_notcomp+1)*(problem[max_of_notcomp]-1) >= g:
        solved += ceil((g - score)/(100*(max_of_notcomp+1)))
        score += ceil((g - score)/(100*(max_of_notcomp+1)))*100*(max_of_notcomp+1)

    if score >= g:
        ans = min(ans, solved)
print(ans)

Solution (Python):
D, G = map(int, input().split())
p = []
c = []
for i in range(0, D):
    a, b = map(int, input().split())
    p.append(a)
    c.append(b)
    
minimum = 2**31   

for i in range(2**D):
    count = 0
    score = 0
    max_j = 0
    addcount = 0
    for j in range(D):
        if (i>>j & 1):
            score += 100 * (j+1) * p[j] + c[j]
            count += p[j]
        if (~i>>j & 1):
            max_j = j
    if score >= G:
        minimum = min(minimum, count)
    else:
        while score < G:
            score += 100 * (max_j + 1)
            addcount += 1
            count += 1
        if addcount <= p[max_j]:
            minimum = min(minimum, count)

print(minimum)

Solution (Python):
from itertools import product
from math import ceil
D,G = map(int,input().split(" "))
p,c = [0]*D,[0]*D

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

ans = float('inf')
for pat in range(1<<D):
    point,prob,maxv = 0,0,0
    for b in range(D):
        if (pat >> b) & 1:
            point += ((100*(b+1))*p[b] + c[b])
            prob += p[b]
        else:
            maxv = max(maxv,b+1)

    if point >= G:
        ans = min(ans,prob)

    elif maxv != 0:
        if G <= (point + (maxv*100)*p[maxv-1]):
            ans = min(ans,prob+ceil((G-point)/(maxv*100)))

print(ans)

Solution (Python):

ranknum,goal = list(map(int,input().split()))
probnum = [0]*ranknum
bonus = [0]*ranknum
compscore = [0]*ranknum

for i in range(ranknum):
    probnum[i], bonus[i] = list(map(int,input().split()))
    
    compscore[i] = 100*(i+1)*probnum[i] + bonus[i]

from itertools import product
from math import ceil


minprob = 1001


for c in product(range(2),repeat=ranknum):
    score = 0
    solvedprob = 0
    notcompedindex = -1

    
    for i in range(ranknum):
        if c[i] == 1:
            score +=  compscore[i]
            solvedprob +=  probnum[i]
        
        else:
            notcompedindex = i

    
    
    if score < goal and score+100*(notcompedindex+1)*(probnum[notcompedindex]-1) >= goal:
        solvedprob += ceil((goal - score)/(100*(notcompedindex+1)))
        score += ceil((goal - score)/(100*(notcompedindex+1)))*100*(notcompedindex+1)
    
    
    if score >= goal:
        minprob = min(minprob, solvedprob)  

print(minprob)

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

Solution (Python):
import itertools
d,c=map(int, input().split())
p=[list(map(int, input().split())) for i in range(d)]
al=list(itertools.product(range(2),repeat=d))
ans=1000
for i in al:
    count=0
    score=0
    if 0 not in i:continue
    last0=d-list(reversed(i)).index(0)-1
    for j in range(d):
        count+=i[j]*p[j][0]
        score+=i[j]*p[j][1]+i[j]*p[j][0]*(j+1)*100
    
    if score>=c:ans=min(ans,count)
    elif (c-score)/((last0+1)*100)<p[last0][0]:ans=min(ans,count+(c-score+last0*100)//((last0+1)*100))
if d==1:print(1)
else:print(ans)

Solution (Python):
d,g = map(int,raw_input().split())

arr = []

for i in range(d):
	arr.append(map(int,raw_input().split()))


ans = float("inf")
for i in range(2**d-1,-1,-1):
	b = bin(i)[2:].zfill(d)
	count = 0
	point = 0
	for j in range(d-1,-1,-1):
		if b[j] == "1":
			count += arr[j][0]
			point += (j+1) * 100 * arr[j][0] + arr[j][1]
	if point < g:

		for j in range(d-1,-1,-1):

			if b[j] == "0":
				t = 0
				while point < g and arr[j][0]-t > 1:
					point += (j+1) * 100
					t += 1
					count += 1

	if point < g:
		continue
	ans = min(ans, count)

print ans

Solution (Python):

import itertools

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

pi = []
ci = []
score_i_c = []
score_i_h = []
for i in range(D):
    p_t, c_t = map(int, input().split())
    pi.append(p_t)
    ci.append(c_t)
    tmp = p_t * 100 * (i + 1) + c_t
    score_i_c.append((i,tmp,p_t))
    tmp = (p_t - 1) * 100 * (i + 1)
    score_i_h.append((i,tmp,p_t))


step1_list = []
for i,score,num in score_i_h:
    if score >= G:
        step1_list.append((i,score,num))

ans_list = []
if len(step1_list) > 0:
    min_i , _, _ = step1_list[-1]
    for i , score, num in step1_list:
        tmp_score = 0
        tmp_num = 0
        for i in range(pi[min_i]):
            if tmp_score >= G:
                break
            else:
                tmp_score += (min_i+1) * 100
                tmp_num  += 1
        ans_list.append(tmp_num)


step1_list = []
for i in range(D):
    tmp = itertools.combinations(score_i_c, i+1)
    step1_list.extend(list(tmp))


sum_list = []
for l in step1_list:
    numbers = []
    sum_score = 0
    sum_num = 0
    for i,score,num in l:
        numbers.append(i)
        sum_score += score
        sum_num += num

    if sum_score >= G:
        sum_list.append((numbers,sum_score,sum_num))
















for min_numbers,min_score,min_num in sum_list:
    for min_i in min_numbers:
        tmp_score = min_score - score_i_c[min_i][1]
        tmp_num = min_num - score_i_c[min_i][2]

        for i in range(pi[min_i]):
            if tmp_score >= G:
                break
            tmp_score += (min_i+1) * 100
            tmp_num  += 1

        ans_list.append(tmp_num)



print(min(ans_list))

Solution (Python):

D_MAX = 10
P_MAX = 100

num_and_pnt = lambda x: [int(x[0]), int(x[1]) // 100]
D, G = num_and_pnt(input().split())

pc = [num_and_pnt(input().split()) for i in range(D)]

G_list = [(i + 1) * x[0] + x[1] for i, x in enumerate(pc)]
cnt_list = [x[0] for i, x in enumerate(pc)]
idx = [map(int, format(i, "b")) for i in range(2 ** D)]


table = [ (i, sum([((i // (2 ** j)) % 2) * G_list[j] for j in range(D)]), sum([((i // (2 ** j)) % 2) * cnt_list[j] for j in range(D)])) for i in range(2 ** D)] 

mincnt = D_MAX * P_MAX
for i, (G_last, cnt_last) in enumerate(zip(G_list, cnt_list)):
    for j, G_comp, cnt_comp in filter(lambda x: (((x[0] // (2 ** i)) % 2 == 0) and (x[1] <= G < x[1] + G_last) and (x[2] < mincnt)), table):
        
        cnt_last_tmp = min((-((G_comp - G) // (i + 1)), cnt_last))
        if cnt_comp + cnt_last_tmp < mincnt: mincnt = cnt_comp + cnt_last_tmp

print(mincnt)

Solution (Python):
import math

d, g = map(int, input().split())
p, c = [], []
for i in range(d):
    pi, ci = map(int, input().split())
    p.append(pi)
    c.append(ci)
compl = [100 * (i+1) * p[i] + c[i] for i in range(d)]

ans = 1e9
for i in range(2 ** d):
    score = num = 0
    for j in range(d):
        if (i >> j) & 1:
            score += compl[j] 
            num += p[j] 
        else:
            
            rest_idx = j
    if score < g:
        need = math.ceil((g - score) / (100 * (rest_idx + 1)))
        if need >= p[rest_idx]:
            continue
        num += need
    ans = min(ans, num)
print(ans)

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

def function(G, i):
	if i==0:
		return 1e9
	n=min(G//(i*100), PC[i][0])
	s=n*i*100
	if n==PC[i][0]:
		s+=PC[i][1]
	if s<G:
		n+=function(G-s, i-1)
	return min(n, function(G,i-1))
print(function(G, D))

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

    mincnt = 999999999
    for i in range(1 << 2 * d):
        score = 0
        cnt = 0
        for j in range(d):
            if i & (1 << j):
                score += a[j]*(j+1)*100 + b[j]
                cnt += a[j]

        for j in range(d-1, -1, -1):
            if not(i & (1 << j)):
                if score > g:
                    break
                s = g - score
                if s % ((j+1)*100) == 0:
                    c = min(a[j], s // ((j + 1) * 100))
                    cnt += c
                    score += c * ((j + 1) * 100)
                else:
                    c = min(a[j], s // ((j + 1) * 100))
                    cnt += c + 1
                    score += (c+1) * ((j + 1) * 100)
                break
        if score < g:
            continue
        if cnt < mincnt:
            mincnt = cnt
    return mincnt

print(after_explain())

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

def solve(g, i):
    if i <= 0:
        return 1e9
    n = min(int(g / (100 * i)), p[i - 1])
    s = 100 * i * n
    if n == p[i - 1]:
        s += c[i - 1]
    if g > s:
        n += solve(g - s, i - 1)
    return min(n, solve(g, i - 1))

print(solve(g, d))

Solution (Python):


""" ビット全検索をちゃんと使ってみる版3 """

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


class ScoreSet:
    def __init__(self, times, score):
        self.times = times
        self.score = score


class ScoreSetSum:
    def __init__(self, times, score, bool_list):
        self.times = times
        self.score = score
        self.bool_list = bool_list


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


scoreSetSumList = [0] * (1<<D)
for i in range(1<<D):
    times_tmp = 0
    score_tmp = 0
    bool_list = [False] * D
    for j in range(D):
        if 1 & i>>j == 1:
            times_tmp += scoreSetList[j].times
            score_tmp += scoreSetList[j].score
            bool_list[j] = True
    scoreSetSumList[i] = ScoreSetSum(times_tmp, score_tmp, bool_list)


ans = float("inf")
for scoreSetSum in scoreSetSumList:
    tmp = float("inf")
    
    if scoreSetSum.score >= G:
        tmp = scoreSetSum.times
    else:
        
        for i in range(D-1, -1, -1):
            if scoreSetSum.bool_list[i] == False:
                score = scoreSetSum.score
                times = scoreSetSum.times
                
                for j in range(scoreSetList[i].times):
                    score += 100*(i+1)
                    times += 1
                    
                    if score >= G:
                        tmp = times
                        break
                    
                break
    
    ans = min(ans, tmp)

print(ans)