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 heapq





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





total = [100*(i+1)*p[i] + c[i] for i in range(D)]
total





ans = []
for i in range(2 ** D):

    point = 0
    mondaisu = 0
    nokori = []
    for j in range(D):
        if i % 2 == 1:
            point += total[j]
            mondaisu += p[j]
        else:
            heapq.heappush(nokori, (-100 * (j+1) * (p[j]-1), j))
        i //= 2

    if point >= G:
        ans.append(mondaisu)
    else:
        po, ind = heapq.heappop(nokori)
        if point + (-po) >= G:
            ans.append(mondaisu + (G-point+100*(ind+1)-1)//(100*(ind+1)) )

        





ans





print(min(ans))

Solution (Python):
d,g=map(int,input().split())
p=[0]
c=[0]
p_num=0
for i in range(d):
    P,C=map(int,input().split())
    p_num+=P
    p.append(P)
    c.append(C)
dp=[0]*(p_num+1)
for j in range(1,d+1):
    for k in range(1,p[j]+1):
        if k==1:
            t_dp=dp[:]
            
        if k==p[j]:
            cc=100*j*k+c[j]
        else:
            cc=100*j*k
            
        for l in range(1,p_num+1):
            if l>=k:
                dp[l]=max(dp[l],t_dp[l-k]+cc)                
for i in range(p_num+1):
    if dp[i]>=g:
        print(i)
        break

Solution (Python):
import sys

def main():
    sum=0
    ans=0
    ansc=0
    D,G = map(int,input().split())

    lis=[]
    for x in range(D):
        P,C = map(int,input().split())
        lis.append([P,C])

    op_cnt = D

    for i in range(2 ** op_cnt):
        for j in range(op_cnt):
            if((i>>j) & 1 and i!=0):
                for k in range(1, lis[j][0]+1):
                    sum+=(100*(j+1))
                    ansc+=1
                    if(k==lis[j][0]):
                        sum+=lis[j][1]
                    if(sum>=G):
                        break


        if(sum<G):
            for lef in reversed(range(0, op_cnt)):
                if(~(i>>lef) & 1 and lis[lef][0] != 1):
                    for l in range(1,lis[lef][0]+1):
                        if(sum>=G):
                            break
                        sum+=(100*(lef+1))
                        ansc+=1


        if(ans>=ansc or ans==0):
            ans=ansc

        ansc=0
        sum=0

    print(ans)
main()

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

def dfs(i, g):
    
    
    if i == 0:
        return 10 ** 9
    
    c = min(g//(i*100), L[i][0])
    n = 100 * i *c
    
    if c == L[i][0]:
        n += L[i][1]
    
    if n < g:
        c += dfs(i-1, g-n)
    
    return min(c, dfs(i-1, g))

print(dfs(D, G))

Solution (Python):
D, G = list(map(int, input().split()))
p = [0]*D
c = [0]*D

ans = 10**9


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

for i in range(2**D):
    t = 0
    p_ = 0
    tyu = -1
    for j in range(D):
        if i & (1 << j):
            t += p[j]*100*(j+1) + c[j]
            p_ += p[j]
        else:
            if tyu < j:
                tyu = j



    if t >= G:
        ans = min(ans, p_)
    
    else:
        if tyu != -1:
            for j in range(p[tyu]-1):
                t += 100 * (tyu+1)
                p_ += 1
                if t >= G:
                    ans = min(ans, p_)

    
print(ans)

Solution (Python):
import itertools

def main():
    D,G=map(int,input().split())
    P=[]
    C=[]
    PC = []
    for i in range(D):
        p,c=map(int,input().split())
        PC.append([100*(i+1),p,c,(100*(i+1)*p+c)/p])
        P.append(p)
        C.append(c)
    res = 100000
    for i in itertools.permutations(range(D)):
        tp = G
        tn = 0
        for j in i:
            if tp <= (j+1)*100*P[j]:
                tn += (tp+(j+1)*100-1) // ((j+1)*100)
                break
            else:
                tp -= (j+1)*100*P[j]
                tn += P[j]
                tp -= C[j]
                if tp <= 0:break
        res = min(res,tn)

    return res

print(main())

Solution (Python):
D, G = map(int, input().split())
p = [0 for _ in range(11)]
c = [0 for _ in range(11)]

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

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

print(ans)

Solution (Python):


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

p = []  
c = []  


solve_completely_list = [False] * D


for d in range(D):
    p_i, c_i = map(int, input().split())
    p.append(p_i)
    c.append(c_i)


def dfs(i, solve_completely_list, completed_amount_list):
    if i >= D:
        is_larger_than_G = False    
        
        total_score = 0
        completed_amount = 0
        for d in range(D):
            if solve_completely_list[d]:
                total_score += (d+1) * 100 * p[d] + c[d]
                completed_amount += p[d]


        
        
        
        if total_score < G:
            
            
            max_d = -1
            for d_i in reversed(range(D)):
                if solve_completely_list[d_i] == False:
                    max_d = d_i
                    break
            
            if max_d == -1:
                return

            for p_d in range(p[max_d] - 1):
                total_score += (max_d + 1) * 100
                completed_amount += 1
                if total_score >= G:
                    is_larger_than_G = True
                    break
        else:
            is_larger_than_G = True
        
        if is_larger_than_G:
            completed_amount_list.append(completed_amount)
        return
    

    
    solve_completely_list[i] = True
    dfs(i + 1, solve_completely_list, completed_amount_list)

    
    solve_completely_list[i] = False
    dfs(i + 1, solve_completely_list, completed_amount_list)

completed_amount_list = []    
dfs(0, solve_completely_list, completed_amount_list)
print(min(completed_amount_list))

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

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

for i in range(2**D):
	l = [0]*D
	score = 0
	count = 0
	for j in range(D):
		if i & (1<<j):
			l[j] = 1

	for a,b,num in zip(l,p,range(1,D+1)):
		if a == 1:
			score += b*100*num
			score += c[num-1]
			count += b

	if score < G:
		index = D
		for bit in l[::-1]:
			index -= 1
			if bit == 0:
				break
		tmp = 0
		while True:
			tmp += 1
			if tmp > p[index]:
				break
			if score + tmp*100*(index+1) >= G:
				ans.append(count+tmp)
				break
	else:
		ans.append(count)

print(min(ans))

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

for i in range(d):
    p,c = map(int, input().split())
    pc.append([p,c])
ans = 10**7
for i in range(2**d):
    tmp = 0
    cnt = 0
    r = list(range(1,d+1))
    for j in range(d):
        if(i>>j)&1==1:
            tmp += pc[j][0]*100*(j+1)+pc[j][1]
            cnt += pc[j][0]
            r.remove(j+1)
    if tmp<g:
        plus = max(r)
        n = min(pc[plus-1][0],-(-(g-tmp)//(plus*100)))
        cnt +=n
        tmp += n*plus*100
    if tmp>= g:
        ans = min(ans,cnt)
print(ans)

Solution (Python):
d, g = map(int, input().split())
p = [[i*100] + list(map(int, input().split()))
     for i in range(1, d+1)]
p = list(map(lambda x: x + [x[0] * x[1] + x[2]], p))

res = 1001
for bit in range(2**d):
    score = 0
    cnt = 0
    zero = 0
    for i in range(d):
        if bit & (1 << i):
            score += p[i][3]
            cnt += p[i][1]
        else:
            zero = i
    if score >= g:
        res = min(res, cnt)
    else:
        remaining = (g - score + p[zero][0]-1) // p[zero][0]
        if remaining < p[zero][1]:
            res = min(res, cnt+remaining)

print(res)

Solution (Python):

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

comp_bounas_list = [[int(item) for item in input().split()] for _ in range(D)]

comp_all = []

for i in range(2**D):
    temp = []
    for j in range(D):
        if ((i >> j) & 1) == 1:
            temp.append(1)
        else:
            temp.append(0)
    comp_all.append(temp)




full_num_list = [item[0] for item in comp_bounas_list]

each_comp_point = []
for i, item in enumerate(comp_bounas_list):
    each_comp_point.append((i+1)*100*item[0]+item[1])





temp_point_list = []

for each_pattern in comp_all:
    temp_num = 0
    temp_point = 0
    for j, item in enumerate(each_pattern):
            if item:
                temp_num += full_num_list[j]
                temp_point += each_comp_point[j]

    temp_point_list.append([temp_num, temp_point, each_pattern]) 




over_list = [item for item in temp_point_list if item[1] >= G]



over_combo = min(over_list, key = lambda x:x[0])



under_combo = [item for item in temp_point_list if item[1] < G]





temp_res_list = []
is_search = True

for temp_combo in under_combo:
    temp_bit_list = temp_combo[2]
    temp_res_point = temp_combo[1]
    temp_res_num = temp_combo[0]
    

    
    for j, item in reversed(list(enumerate(temp_bit_list))):
        for _ in range(1, comp_bounas_list[j][0]):
            
            if item==0:
                temp_res_point += (j+1)*100
                temp_res_num += 1

            if temp_res_point >= G:
                temp_res_list.append([temp_res_num, temp_res_point])
                break




if temp_res_list != []:
    res_candi = min(temp_res_list, key=lambda x:x[0])
else:
    res_candi = temp_point_list[-1]

if over_combo[0] <= res_candi[0]:
    print(over_combo[0])
else:
    print(res_candi[0])

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

comp_bounas_list = [[int(item) for item in input().split()] for _ in range(D)]

comp_all = []

for i in range(2**D):
    temp = []
    for j in range(D):
        if ((i >> j) & 1) == 1:
            temp.append(1)
        else:
            temp.append(0)
    comp_all.append(temp)




full_num_list = [item[0] for item in comp_bounas_list]

each_comp_point = []
for i, item in enumerate(comp_bounas_list):
    each_comp_point.append((i+1)*100*item[0]+item[1])





temp_point_list = []

for each_pattern in comp_all:
    temp_num = 0
    temp_point = 0
    for j, item in enumerate(each_pattern):
            if item:
                temp_num += full_num_list[j]
                temp_point += each_comp_point[j]

    temp_point_list.append([temp_num, temp_point, each_pattern]) 




over_list = [item for item in temp_point_list if item[1] >= G]


over_combo = min(over_list, key = lambda x:x[0])



under_combo = [item for item in temp_point_list if item[1] < G]





temp_res_list = []
is_search = True

for temp_combo in under_combo:
    temp_bit_list = temp_combo[2]
    temp_res_point = temp_combo[1]
    temp_res_num = temp_combo[0]
    

    
    for j, item in reversed(list(enumerate(temp_bit_list))):
        for _ in range(1, comp_bounas_list[j][0]):
            
            if item==0:
                temp_res_point += (j+1)*100
                temp_res_num += 1

            if temp_res_point >= G:
                temp_res_list.append([temp_res_num, temp_res_point])
                break



if temp_res_list != []:
    res_candi = min(temp_res_list, key=lambda x:x[0])
else:
    res_candi = temp_point_list[-1]

if over_combo[0] <= res_candi[0]:
    print(over_combo[0])
else:
    print( res_candi[0])

Solution (Python):
d, g = [int(x) for x in input().split()]
g //= 100
problems = {}
max = 0
for i in range(d):
  
  problems[i + 1] = [int(x) for x in input().split()]
  max += problems[i + 1][0]

dp = {} 
dp[0] = 0
for (point, p) in problems.items():
  tmp = list(dp.items())
  num = p[0]
  bonus = p[1] // 100
  for i in range(0, num):
    i += 1
    pt = point * i
    if i == num:
      pt += bonus
    for (k, v) in tmp:
      idx = k + pt
      if idx in dp:
        if dp[idx] > v + i:
          dp[idx] = v + i
      else:
        dp[idx] = v + i

ans = max
for i in dp:
  if i >= g:
    if ans > dp[i]:
      ans = dp[i]

print(ans)

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


ans = float("inf")


for bit in range(1 << D):
    score = 0
    solve = 0
    rest = set(range(1, D + 1))

    for i in range(D):
        
        if (bit>>i) & 1:
            
            score += PC[i][0] * (i + 1) * 100 + PC[i][1]
            solve += PC[i][0]
            
            rest.discard(i + 1)

    
    if score < G:
        target = max(rest)
        n = min(PC[target - 1][0], -((score-G) // (target*100)))
        score += n * target * 100
        solve += n

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

print(ans)

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

def num2bi(x, k):
  
  out=format(x, '0'+str(k)+'b')
  return out
  
n=2**D
counter=sum(pc[i][0] for i in range(D))
for i in range(n):
  a=num2bi(i, D)
  c=0
  p=0
  for j in range(D):
    if a[j]=='1':
      p+=pc[j][0]*(j+1)*100+pc[j][1]
      c+=pc[j][0]
      
  if p<G:
    j=D
    while j>0 and p<G:
      j-=1
      if a[j]=='0':
        temp=(G-p)//(100*(j+1))
        if (G-p)%(100*(j+1))>0:
          temp+=1
          
        if temp<=pc[j][0]-1:
          p+=100*(j+1)*temp
          c+=temp
        else:
          p+=100*(j+1)*(pc[j][0]-1)
          c+=(pc[j][0]-1)
          
  if p>=G:
    counter=min(counter, c)
  
print(counter)

Solution (Python):
D,G = map( int,input().split() )
PC = [ list(map(int,input().split())) for i in range(D) ]
ans = 10**7

for i in range(D):
  score=0
  l=0
  for j in range(PC[i][0]-1):
    score += 100*(i+1)
    l += 1
    if score>=G and ans>l:
      ans=l

for i in range(1,2**D):
  score = 0
  l = 0
  for j,flag in enumerate( list(format(i,"b").zfill(D))[::-1] ):
    if flag=="1":
      score += PC[j][0]*100*(j+1) + PC[j][1]
      l += PC[j][0]
    else:
      k=j
    
  j=0
  while score<G and j<PC[k][0]-1:
    score+=100*(k+1)
    l+=1
    j+=1
  if score>=G and ans>l:
    ans=l
  
print(ans)

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

ans = sum([i[0] for i in pc])

for i in range(2**D):
    search_index = format(i, '0' + str(D) + 'b')
    complete_answered = [i for i, c in enumerate(search_index[::-1]) if c == '1']
    incomplete_answered = list(set(range(D)) - set(complete_answered))
    answered_number = 0
    remaining_score = G
    for j in complete_answered:
        answered_number += pc[j][0]
        remaining_score -= (100 * (j + 1) * pc[j][0] + pc[j][1])
    incomplete_answered = sorted(incomplete_answered, reverse=True)
    for j in incomplete_answered:
        question_number = pc[j][0]
        while remaining_score > 0:
            answered_number += 1
            remaining_score -= 100 * (j + 1)
            question_number -= 1
            if question_number <= 0:
                remaining_score -= pc[j][1]
                break
    if answered_number < ans:
       ans = answered_number
print(ans)

Solution (Python):
d, g = map(int, input().split())
pc = []
a = 9999999
for _ in range(d):
    _p, _c = map(int, input().split())
    pc.append([_p, _c])
for i in range(2 ** d):
    tmp = []
    ans = 0
    n = 0
    for j in range(d):
        if ((i >> j) & 1):
            tmp.append(j)
    for j in tmp:
        ans += (j+1)*100*pc[j][0] + pc[j][1]
        n += pc[j][0]
    if ans >= g:
        if n < a:
            a = n
    else:
        for j in range(len(pc)):
            if not j in tmp:
                plus = 0
                for k in range(pc[j][0]):
                    plus += (j+1)*100
                    if ans + plus >= g:
                        if n + k + 1 < a:
                            ans += plus
                            n += k+1
                            a = n
                            break
print(a)

Solution (Python):
from math import ceil

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

answer = float("inf")
for combination in range(2 ** d):
    score = 0
    solved = 0
    for difficuty in range(d):
        if (combination >> difficuty) & 1:
            score += points[difficuty][0] * 100 * (difficuty + 1) + points[difficuty][1]
            solved += points[difficuty][0]
    if score < g:
        for difficuty in range(d)[::-1]:
            if not (combination >> difficuty) & 1 and g - score < points[difficuty][0] * 100 * (difficuty + 1):
                solved += ceil((g - score) / (100 * (difficuty + 1)))
                break
        else:
            continue
    if answer > solved:
        answer = solved
print(answer)

Solution (Python):



import pdb
import sys
import math
F = sys.stdin

D, G = map(int,F.readline().split())
p = []
c = []
all_score = []
maisu = 0
ans = 0
sum = 0
all_selected = [0]*D
for k in range(D):
    p1, c1 = map(int,F.readline().split())
    p.append(p1)
    c.append(c1)
    all_score.append(100 * (k+1) * p1 + c1)

for bit in range(1<<D):
    for i in range(D):
        if bit & (1<<i):
            all_selected[i] = 1
            sum += all_score[i]
            maisu += p[i]

    nokori = G - sum
    if nokori <= 0:
        if ans == 0:
            ans = maisu
        else:
            ans = min(ans, maisu)
        all_selected = [0]*D
        maisu = 0
        sum = 0
        continue

    for j in range(D)[::-1]:
        if all_selected[j] == 0:
            nokorimaisu = math.ceil(nokori / (100 * (j+1)))
            if nokorimaisu <= p[j]:
                maisu += nokorimaisu
                if ans == 0:
                    ans = maisu
                else:
                    ans = min(ans, maisu)
            break

    all_selected = [0]*D
    maisu = 0
    sum = 0

print(ans)

Solution (Python):
from sys import stdin
f_i = stdin

D, G = map(int, f_i.readline().split())

score_data = []
for i in range(1, D + 1):
    p, c = map(int, f_i.readline().split())
    score = i * 100
    score_data.append((score, p, c))
score_data.sort(reverse=True)

count_rec = []
def dfs(i, score, count, unsolved):
    if score >= G:
        count_rec.append(count)
    elif i == D:
        if unsolved:
            s, p, c = score_data[unsolved[0]]
            remain = G - score
            if s * p >= remain:
                if remain % s == 0:
                    count_rec.append(count + remain // s)
                else:
                    count_rec.append(count + remain // s + 1)
    else:
        s, p, c = score_data[i]
        dfs(i + 1, score + s * p + c, count + p, unsolved)
        dfs(i + 1, score, count, unsolved + [i])

dfs(0, 0, 0, [])
print(min(count_rec))

Solution (Python):

import sys, math, itertools, heapq, collections, bisect, string, copy
input = lambda: sys.stdin.buffer.readline().rstrip().decode('utf-8')
sys.setrecursionlimit(10**8)
inf = float('inf')
mod = 10**9+7
ans = inf
count = 0; pro = 1

d, g = map(int, input().split())
g //= 100
dp=[[inf]*(10**5+10000) for i in range(11)]
dp[0][0]=0
for i in range(d):
    p,c=map(int,input().split());c//=100
    for j in range(10**5+10000):
        if dp[i][j]!=inf:
            dp[i+1][j]=min(dp[i+1][j],dp[i][j])
            for k in range(1,p):
                dp[i+1][j+(i+1)*k]=min(dp[i+1][j+(i+1)*k],dp[i][j]+k)
            dp[i+1][j+(i+1)*p+c] = min(dp[i+1][j+(i+1)*p+c],dp[i][j]+p)
for i in range(g,10**5+10000):
    ans=min(ans,dp[d][i])
print(ans)

Solution (Python):

import sys, math, itertools, heapq, collections, bisect, string, copy
input = lambda: sys.stdin.buffer.readline().rstrip().decode('utf-8')
sys.setrecursionlimit(10**8)
inf = float('inf')
mod = 10**9+7
ans = inf
count = 0; pro = 1

d, g = map(int, input().split())
g //= 100
dp=[[inf]*(10**5*2) for i in range(11)]
dp[0][0]=0
for i in range(d):
    p,c=map(int,input().split());c//=100
    for j in range(10**5*2):
        if dp[i][j]!=inf:
            dp[i+1][j]=min(dp[i+1][j],dp[i][j])
            for k in range(1,p):
                dp[i+1][j+(i+1)*k]=min(dp[i+1][j+(i+1)*k],dp[i][j]+k)
            dp[i+1][j+(i+1)*p+c] = min(dp[i+1][j+(i+1)*p+c],dp[i][j]+p)
for i in range(g,10**5*2):
    ans=min(ans,dp[d][i])
print(ans)

Solution (Python):

import sys, math, itertools, heapq, collections, bisect, string, copy
input = lambda: sys.stdin.buffer.readline().rstrip().decode('utf-8')
sys.setrecursionlimit(10**8)
inf = float('inf')
mod = 10**9+7
ans = count = 0; pro = 1

d,g=map(int,input().split());g//=100
D=collections.defaultdict(lambda: inf )
D[0]=0
for i in range(1,d+1):
    p,c=map(int,input().split());c//=100
    
    
    
    S=D.copy()
    for key,value in S.items():
        for k in range(1,p):    
        
            D[key+i*k] = min(D[key+i*k],S[key]+k)
        D[key+i*p+c] = min(D[key+i*p+c],S[key]+p)
ans=inf
for key,value in D.items():
    
    if key>=g:
        ans=min(ans,value)
print(ans)

Solution (Python):

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

p = [0] * D
c = [0] * D

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


ans = 10000
for n in range(2**D):
    bnum = (bin(n)[2:]).zfill(D)
    score = 0
    cnt = 0
    for i,s in enumerate(bnum):
        if s == "1":
            
            score += (i+1)*100*p[i] + c[i]
            cnt += p[i]
    
    
    if score >= G:
        ans = min(ans, cnt)
    else:
        for i,s in enumerate(reversed(bnum)):
            if s == "0":
                rest = G - score
                if rest / ((D-i)*100) <= p[i]:
                    
                    cnt += math.ceil(rest / ((D-i)*100))
                    ans = min(ans, cnt)


print(ans)

Solution (Python):
from itertools import product

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

ans = float('inf')
for ptn in product([0, 1], repeat=D):
    total = 0
    cnt = 0
    for i in range(D):
        total += score[i][3] * ptn[i]
        cnt += score[i][1] * ptn[i]

    if 0 in ptn[::-1]:
        i = D - 1 - ptn[::-1].index(0)
        x = score[i]
    else:
        x = score[-1]

    for i in range(x[1]):
        if total >= G:
            break
        total += x[0]
        cnt += 1

    if total < G:
        cnt = float('inf')
    ans = min(ans, cnt)
print(ans)

Solution (Python):
D,G = map(int, input().split(' '))
prb = []
for i in range(D):
    prb.append(list(map(int, input().split(' '))))
p_cmp = []
for i in range(D):
    p_cmp.append((i+1)*100*prb[i][0]+prb[i][1])
ans = 10**18

for b in range(2**D):
    Gtmp = G
    pslv = 0
    binstr = format(b,'b')
    binstr = binstr.zfill(D)
    for i, x in enumerate(binstr):
        if x == "1":
            Gtmp -= p_cmp[i]
            pslv += prb[i][0]
        if x == '0':
            continue
    if Gtmp > 0:
        for i, x in enumerate(binstr[::-1]):
            if x == "1":
                continue
            if x == '0':
                j = D-i-1
                if Gtmp < prb[j][0] * (j+1) * 100:
                    pslv += (Gtmp + (j+1)*100-1)//((j+1)*100)
                    Gtmp = 0
                    ans = min(ans, pslv)
                    break
                else:
                    break
                break
    if Gtmp <= 0:
        ans = min(ans, pslv)

print(ans)

Solution (Python):
d,g=map(int,input().split())
pc={_:(list(map(int,input().split()))) for _ in range(d)}
bin_lst=[]
d2=2**d
for x in range(d2):
    buf=bin(x)[2:]
    len_buf=len(buf)
    if len_buf<d:
        buf='0'*(d-len_buf)+buf
    bin_lst.append(buf)
lst_cnt=[]
buf_lst=[]
for x in bin_lst:
    cnt=0
    buf_int=0
    len_x=len(x)
    for y in range(d):
        if x[y]=="1":
            buf_lst=pc[y]
            buf_int+=(y+1)*100*buf_lst[0]+buf_lst[1]
            cnt+=buf_lst[0]
    if buf_int<g:
        buf_index=x.rfind("0")
        buf_lst=pc[buf_index]
        i=buf_lst[0]
        for z in range(1,i):
            if buf_int+(buf_index+1)*100*z>=g:
                buf_int+=(buf_index+1)*100*z
                cnt+=z
                break
    if buf_int>=g:
        lst_cnt.append(cnt)
print(min(lst_cnt))

Solution (Python):
D , G = map(int,input().split())
bonus = []
question_cnt = []
for i in range(D):
    p , c = map(int,input().split())
    question_cnt.append(p)
    bonus.append(c)
ans = float('inf')
for bit in range(2 ** D):
    sum_val = 0
    tmp_ans = 0
    Flag = False
    for j in range(D):
        if bit >> j & 1:
            sum_val += question_cnt[j] * (j + 1) * 100 + bonus[j]
            tmp_ans += question_cnt[j]
    if sum_val < G:
        for j in range(D-1 , - 1 , -1):
            if Flag:
                break
            if not bit >> j & 1:
                Flag = True
                for k in range(question_cnt[j]):
                    sum_val += (j + 1) * 100
                    tmp_ans += 1
                    if sum_val >= G:
                        break
    if tmp_ans < ans and sum_val >= G:
        ans = tmp_ans
print(ans)

Solution (Python):
D,G = map(int,input().split())
pc = [list(map(int,input().split())) for i in range(D)]
ans = 10**9
for i in range(2**D):
  score=0
  n=0
  done=""
  for j in range(D):
    if (i>>j)&1:
      score += 100*(j+1)*pc[j][0]+pc[j][1]
      n += pc[j][0]
      done+=str(j)
  if score < G:
    for k in range(D):
      if str(D-k-1) in done:
        continue
      for l in range(pc[D-k-1][0]):
        score += 100*(D-k)
        n += 1
        if score >= G:
          break
      if score >= G:
        break
  ans = min(ans,n)
print(ans)

Solution (Python):
from collections import Counter,defaultdict,deque
import sys
import bisect
import math
import itertools
import string
import queue
import copy


from itertools import permutations, combinations
from heapq import heappop, heappush
input = sys.stdin.readline
sys.setrecursionlimit(10**8)
mod = 10**9+7

def inp(): 
    return int(input())
def inpm(): 
    return map(int,input().split())
def inpl(): 
    return list(map(int, input().split()))
def inpls(): 
    return list(input().split())
def inplm(n): 
    return list(int(input()) for _ in range(n))
def inpll(n): 
    return sorted([list(map(int, input().split())) for _ in range(n)])


def main():
    d,g=inpm()
    p,c,t=[],[],[]
    ans=10**5
    for i in range(d):
        x,y=inpm()
        p.append(x)
        c.append(y)
        t.append(x*(i+1)*100+y)
    for num in range(1,d+1):
        for groop in combinations(range(d),num):
            total = 0
            member = 0
            for e in groop:
                total += t[e]
                member += p[e]
            if total < g:
                continue
            notgroup = []
            for i in range(d):
                if i not in groop:
                    notgroup.append(i)
            max_e=-1
            if len(notgroup)>0:
                max_e = max(notgroup)
            if max_e == d-1 or max_e==-1:
                pre_ans = 0
                for i in groop:
                    pre_ans += p[i]
                ans = min(ans,pre_ans)
            if max_e!=d-1:
                for way in range(max_e+1,d):
                    if total - c[way] - (way+1)*100 <g:
                        continue
                    diff = total - g - c[way] - (way+1)*100
                    pre_ans = member - 1 - min(p[way]-1,diff//((way+1)*100))
                    ans = min(ans,pre_ans)
    print(ans)

if __name__ == "__main__":
    main()

Solution (Python):
D,G = map(int,input().split())
PC = [list(map(int,input().split())) for _ in range(D)]
comp = [PC[i][0]*(i+1)*100+PC[i][1] for i in range(D)]
ans = float("inf")
for i in range(2**D):
    Gt = 0
    cnt = 0
    lis = [0]*D
    tmp = str(bin(i))[2:]
    for j in range(len(tmp)):
        lis[-j-1] = int(tmp[-j-1])
    for k in range(D):
        if lis[k]:
            Gt += comp[k]
            cnt += PC[k][0]
        else:
            hanpa = k
    if Gt>=G:
        ans = min(ans,cnt)
        continue
    if G-Gt > (PC[hanpa][0]-1)*(hanpa+1)*100:
        continue
    cnt += -(-(G-Gt)//((hanpa+1)*100))
    ans = min(ans,cnt)
print(ans)

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

for i in range(2 ** D):
    a = 0
    b = 0
    for j in range(D):
        if (i >> j) & 1 :
            a += 100 * P[j] * (j + 1) + C[j]
            b += P[j]
    for k in range(D - 1, -1, -1):
        if (i >> k) & 1:
            continue
        if a >= G:
            break
        for l in range(P[k]):
            a += 100 * (k + 1)
            b += 1
            if a >= G:
                break
    ans = min(ans, b)
print(ans)