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. 



Sample input:
2 700
3 500
5 800


Sample output:
3

Submission status: Runtime Error

Solution code:
import math
D, G = map(int, input().split())
L = []
for i in range(D):
    p, c = map(int, input().split())
    L.append([i, p, c, 100*i*p, 100*i*p+c, (100*i*p+c)/p])
L.sort(key=lambda x: x[-1], reverse=True)
# print(L)
num = 0
for j in range(D):
    if G > L[j][4]:
        G -= L[j][4]
        num += L[j][1]
        L[j][1:] = [0, 0, 0, 0, 0]
    else:
        num1 = L[j][1]
        M = L[:]
        M.sort(key=lambda x: x[0], reversed=True)
        num2 = 100000
        for k in range(D):
            if M[k][3] >= G:
                num2 = math.ceil(G/(100*k))
        num += min(num1, num2)
        break
print(num)

Submission status: Runtime Error

Solution code:
import math as m
from fractions import gcd
D,G = map(int,input().split())
info = [list(map(int,input().split())) for i in range(D)]
a = info[0][0]
L = []
for i in range(1,D):
    b = info[i][0]
    lcm = (a * b) // gcd(a,b)
    a = lcm
for i in range(1,D+1):
    p = info[i-1][0]
    c = info[i-1][1]
    L.append([lcm*100*i + c, i, p, c])
goal = G
count = 0
# 見かけの点数でソート
L.sort()
# 見かけの点数が大きい順から問題を解いていく
# i番目を全問解いた見かけのiscoreについて　
# goal - iscore >= 0 ならば i番目を解くことは確定
for i in range(D-1,-1,-1):
    iscore = 100 * L[i][1] * L[i][2] + L[i][3]
    if goal - iscore >= 0:
        goal -= iscore
        count += L[i][2]
        if goal == 0:
            break
# goal - iscore < 0 ならば　
# i番目をj問解いたscore_jが goal - score_j <= 0 となるような 最小のjをメモ
# まだ解いていない他の問題についても同様にjをメモ(存在しない場合もあり)　これらのうち最小のjを採用する
    elif goal - iscore < 0:
        adopt = 100
        for k in range(i,-1,-1):
            score = 100 * L[k][1] * L[k][2] + L[k][3]
            if goal - score <= 0:
                j = min(m.ceil(goal/(100 * L[k][1])),L[k][2])
                if j < adopt:
                    adopt = j
        count += adopt
        break
print(count)

Submission status: Runtime Error

Solution code:
import numpy as np
import math
import itertools

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

p_c_list = np.array([tuple(map(int, [100 * (i + 1)] + input().split())) for i in range(D)])
summary = []

masks = itertools.product([False, True], repeat=len(p_c_list))

ret = np.inf
for mask in masks:
  maskedarr = p_c_list[np.array(mask), :]
  comp_sum = (maskedarr[:, 0] * maskedarr[:, 1] + maskedarr[:, 2]).sum()
  suc_num = maskedarr[:, 1].sum()
  if comp_sum < G:
    amari = (G - comp_sum) / p_c_list[~np.array(mask), 0][-1]
    if amari < p_c_list[~np.array(mask), 1][-1]:
      if ret > suc_num + amari:
        ret = suc_num + amari
    else:
      continue
      
print(int(ret))

Submission status: Runtime Error

Solution code:
D,G=map(int,input().split())
A=[]
for i in range(D):
    p,c=map(int,input().split())
    A.append([p,c])
a=10**9
for j in range(2**D):
    b=format(j, 'b')
    B="0"*(D-len(b))+str(b)
    S=[]
    N=[]
    for k in range(D):
        S.append((A[k][0]*(k+1)*100+A[k][1])*int(B[-k-1]))
        N.append(A[k][0]*int(B[-k-1]))
        if sum(S)>=G:
            s=sum(N)
            if a>s:
                a=s
        else:
            for l in range(D):
                if B[l]=="0" and (G-sum(S))<=((D-l)*100)*(A[-l-1][0]-1) :
                    s=sum(N)+((G-sum(S))//((D-l)*100))+min(1,((G-sum(S))%((D-l)*100)))
                    break
            if a>s:
                a=s
print(a)

Submission status: Runtime Error

Solution code:
D,G=map(int,input().split())
A=[]
for i in range(D):
    p,c=map(int,input().split())
    A.append([p,c])
a=10**9
for j in range(1,2**D):
    b=format(j, 'b')
    B="0"*(D-len(b))+str(b)
    S=[]
    N=[]
    for k in range(D):
        S.append((A[k][0]*(k+1)*100+A[k][1])*int(B[-k-1]))
        N.append(A[k][0]*int(B[-k-1]))
        if sum(S)>=G:
            s=sum(N)
            if a>s:
                a=s
        else:
            for l in range(D):
                if B[l]=="0" and (G-sum(S))<=((D-l)*100)*(A[-l-1][0]-1) :
                    s=sum(N)+((G-sum(S))//((D-l)*100))+min(1,((G-sum(S))%((D-l)*100)))
                    break
            if a>s:
                a=s
print(a)

Submission status: Runtime Error

Solution code:
from collections import defaultdict

D,G=map( int, raw_input().split() )
P=[ map( int, raw_input().split() ) for i in range(D) ] 

N=10**5+2000
dp= [   [ float("inf") for i in range(N+1)] for idx in range(D+1)  ]
dp[0][0]=0

for idx, x  in enumerate(P):
	m=idx+1	#money
	p,c=x[0], x[1]/100
	for i in range(N,-1,-1):
		if dp[idx][i]!=float("inf"):
			for j in range(p,-1,-1):	# j= problems count   , idx = score of a problem
				if j==p:
					dp[idx+1][i+m*j+c]=min( dp[idx+1][i+m*j+c] , dp[idx][i]+j )
				else:
					dp[idx+1][i+m*j]=min( dp[idx+1][i+m*j] , dp[idx][i]+j )


ans=float("inf")

for i in range(G/100,N):
	ans=min(ans, dp[-1][i])

print ans

Submission status: Runtime Error

Solution code:
from collections import defaultdict

D,G=map( int, raw_input().split() )
P=[ map( int, raw_input().split() ) for i in range(D) ] 

N=10**5
dp= [ float("inf") for i in range(N+1)]
dp[0]=0

for idx, x  in enumerate(P):
	idx+=1
	p,c=x[0], x[1]/100
	for i in range(N,-1,-1):
		if dp[i]!=float("inf"):
			for j in range(p+1):	# j= problems count   , idx = score of a problem
				dp[i+idx*j]=min( dp[i+idx*j] , dp[i]+j )
				if j==p:
					dp[i+idx*j+c]= min( dp[i+idx*j+c], dp[ i+idx*j ] )


ans=float("inf")

for i in range(G/100,N):
	ans=min(ans, dp[i])

print ans

Submission status: Runtime Error

Solution code:
#Dが10でpiが100…、データサイズも時間も無理そう。なので工夫する。
#コンプボーナスがなければ高得点の問題から解けばよいのだが、コンプボーナスがあるので
#１問の得点は低くとも全問解くと有利となることがある。
#なので、基本的にpi全問解くが、中途半端に解くiが１つある
#１．序盤は効率良く解くために、レート(総得点/pi)が高い順に解く
#２．Gを超えてしまった場合は、最小回答数でGを超えるものを探す
#	２．１．総得点で探す
#	２．２．残されている最高得点の1問回答(コンプなしで)で探す

#npのインポートに220msかかる
import numpy as np
#from numpy import argsort, ceil

def main():
    D, G = (int(i) for i in input().split())
    P = [0] * D
    C = [0] * D
    for i in range(D):
        p, c = [int(x) for x in input().split()]
        P[i] = p
        C[i] = c

    #print(P,C)

    totals = [0] * D
    rates = [0.0] * D
    for i in range(D):
        totals[i] = 100*P[i] + C[i]
        rates[i] = (totals[i] / P[i])

    #print(totals,rates)

    index_sorted_rates = np.argsort(rates)[::-1]
    #print(index_sorted_rates)

    sum = 0
    count = 0
    for i in range(D):
        index = index_sorted_rates[i]
        total = totals[index]
        if (G <= sum + total):
            break
        sum += total
        count += P[index]
        print(sum, count)

    #他のtotalを探す
    list = index_sorted_rates[i:]
    res = (G - sum)
    c = []
    for i in list:
        if (res < totals[i]):
            c.append(P[i])
    c = min(c)

    #最高得点の1問回答はc以下なら、そちらを採用
    i = max(list)
    if (P[i] < c):
        c2 = np.ceil(res / (100*i))
        if (c2 < c):
            return count + c2

    return count + c

print(main())

Submission status: Runtime Error

Solution code:
d, g = (int(i) for i in input().split())
p = [[int(i) for i in input().split()] for i in range(n)]
ans = 1000

for i in range(1 << d): # 4
    score = 0
    num = 0
    rest = 0
    for j in range(d): # 2
        if ((i >> j) & 1) == 1: # 0 1  2=10
            score += p[j][0] * 100 * (j + 1) + p[j][1]
            num += p[j][0]
        else:
            rest = j
    if score < g:
        need = (g - score) // (100*(rest+1))
        if need > p[rest][0] - 1: # 0だったところの中で一番大きいところの問題数-1よりも必要手数が多かったら初めに戻る
            continue
        else:
            num += need
    ans = min(ans, num)
print(ans)

Submission status: Runtime Error

Solution code:
    d, g = map(int, input().split())
    pc = [list(map(int, input().split())) for _ in range(d)]
     
    ans = 1000
    for i in range(1 << d):
    	score = 0
    	num = 0
    	rest = 0
    	for j in range(d):
    		if ((i >> j) & 1) == 1:
    			score += pc[j][0]*100*(j+1) + pc[j][1]
    			num += pc[j][0]
    		else:
    			rest = j
    	if score < g:
    		need = (g-score-1)//(100*(rest+1)) + 1
    		if need > pc[rest][0]-1:
    			continue
    		else:
    			num += need
    	ans = min(ans, num)
     
    print(ans)

Submission status: Runtime Error

Solution code:
d, g = (int(i) for i in input().split())
p = [[int(i) for i in input().split()] for i in range(n)]
ans = 1000

for i in range(1 << d): # 4
    score = 0
    num = 0
    rest = 0
    for j in range(d): # 2
        if ((i >> j) & 1) == 1: # 0 1  2=10
            score += p[j][0] * 100 * (j + 1) + p[j][1]
            num += p[j][0]
        else:
            rest = j
    if score < g:
        need = (g - score - 1) // (100*(rest+1))
        if need > p[rest][0] - 1: # 0だったところの中で一番大きいところの問題数-1よりも必要手数が多かったら初めに戻る
            continue
        else:
            num += need
    ans = min(ans, num)
print(ans)

Submission status: Runtime Error

Solution code:
d, g = (int(i) for i in input().split())
p = [[int(i) for i in input().split()] for i in range(n)]
ans = 1000

for i in range(1 << d): # 4
    score = 0
    num = 0
    rest = 0
    for j in range(d): # 2
        if ((i >> j) & 1) == 1: # 0 1  2=10
            score += p[j][0] * 100 * (j + 1) + p[j][1]
            num += p[j][0]
            print("num:",num)
        else:
            rest = j
            print("rest:",rest)
    if score < g:
        need = (g - score) // (100*(rest+1))
        if need > p[rest][0] - 1: # 0だったところの中で一番大きいところの問題数-1よりも必要手数が多かったら初めに戻る
            print("need:", need)
            continue
        else:
            num += need
            print("num2:",num)
    ans = min(ans, num)
    print("ans:", ans)
print(ans)

Submission status: Runtime Error

Solution code:
d, g = map(int, input().split())
o, c = zip(*[map(int, input().split()) for _ in range(d)])

comp = [(i+1)*o[i]+c[i]//100 for i in range(d)]

G = g//100

# 大きい数（全問解く)
ans = sum(o)

for j in range(2**d):
    tmp = bin(j)
    ope = tmp[2:len(tmp)].zfill(d)

    now = 0  # 得点
    f = 1
    num = 0  # 問題数
    re = [[0, 0]]  # とかなかった問題の配列

    for i in range(d):
        if ope[i] == '1':
            now += comp[i]
            num += o[i]
        else:
            re.append([(i+1)*(o[i]-1), i+1])

        re.sort()
        re.reverse()

    if now < G:
        if now+re[0][0] < G:
            # 答えにならない
            now = sum(p)
            f = -1
        else:
            # 中途半端に解く問題数
            K = (G - now)//re[0][1]

            # 中途半端に解くときに、%==0ならちょうどgoalになるけど、それ以外の時は、ちょっとだけ点数が足りないから問題をもう一問解く
            if (G % re[0][1] > 0):
                K = K+1
            num += K
    if num < ans and f > 0:
        ans = num
print(ans)

Submission status: Runtime Error

Solution code:
d, g = map(int, input().split())
o, c = zip(*[map(int, input().split()) for _ in range(d)])

comp = [(i+1)*o[i]+c[i]//100 for i in range(d)]
print(o, c)
print(comp)

G = g//100

# 大きい数（全問解く)
ans = sum(o)

for j in range(2**d):
    tmp = bin(j)
    ope = tmp[2:len(tmp)].zfill(d)

    now = 0  # 得点
    f = 1
    num = 0  # 問題数
    re = [[0, 0]]  # とかなかった問題の配列

    for i in range(d):
        if ope[i] == '1':
            now += comp[i]
            num += o[i]
        else:
            re.append([(i+1)*(o[i]-1), i+1])

        re.sort()
        re.reverse()

    if now < G:
        if now+re[0][0] < G:
            # 答えにならない
            now = sum(p)
            f = -1
        else:
            # 中途半端に解く問題数
            K = (G - now)//re[0][1]

            # 中途半端に解くときに、%==0ならちょうどgoalになるけど、それ以外の時は、ちょっとだけ点数が足りないから問題をもう一問解く
            if (G % re[0][1] > 0):
                K = K+1
            num += K
    if num < ans and f > 0:
        ans = num
print(ans)

Submission status: Runtime Error

Solution code:

x = input().split(' ')
cnt = int(x[0])
past_num = int(x[1])

point_list = []
bonus_list = []
#回数を保持
sum_cnt = 0
#計算途中の合計を保持
sum_sum = 0

for y in range(cnt):
    input_list = input().split(' ')
    point_list.append(int(input_list[0]))
    bonus_list.append(int(input_list[1]))


max_len = len(point_list) -1



while sum_sum <= past_num:
    min_index = point_list.index(min(point_list))
    min_cnt = point_list[min_index]
    #回数が最小のインデックスを求めて計算開始
    #x*100+min_index+bouns_listを全てのパターンで計算する
    #最小であればその配列をpopする最小でなければ2番目の最小回数で計算を行うこれを繰り返しす
    count = 1
    min_sum = (min_index + 1) * 100 * point_list[min_index] + bonus_list[min_index]
    out_min_sum = 0
    sum = 0
    flg = 0
    for x in range(max_len):
        sum = count * 100 * min_cnt 
        
        if sum < min_sum:
            out_min_sum = min_sum
            min_sum = sum
            sum_cnt += point_list[count-1]
            sum_sum += sum
            point_list.pop(count-1)
            bonus_list.pop(count-1)
            flg = 1
        count += 1
    if flg == 0:
        point_list.pop(min_index)
        bonus_list.pop(min_index)
        sum_sum += min_sum
        sum_cnt += min_cnt
    else:
        flg = 0

print(sum_cnt)

Submission status: Runtime Error

Solution code:
flg = 0

def jage(sum,a,b,c,d,flg2):
    global flg
    if sum == 7 and flg2== 0:
        print(str(d)+'+'+str(c)+'+'+str(b)+'+'+str(a) + '='+str(sum))
        flg = 1


num_text = list(input())
a = int(num_text[3])
b = int(num_text[2])
c = int(num_text[1])
d = int(num_text[0])
sum = 0
flg = 0
sum = d + c + b + a
if sum == 7 and flg== 0:
    print(str(d)+'+'+str(c)+'+'+str(b)+'+'+str(a) + '='+str(sum))
    flg = 1
sum = d + c + b - a
if sum == 7 and flg== 0:
    print(str(d)+'+'+str(c)+'+'+str(b)+'-'+str(a) + '='+str(sum))
    flg = 1
sum = d + c - b + a
if sum == 7 and flg== 0:
    print(str(d)+'+'+str(c)+'-'+str(b)+'+'+str(a) + '='+str(sum))
    flg = 1
sum = d + c - b - a
if sum == 7 and flg== 0:
    print(str(d)+'+'+str(c)+'+'+str(b)+'-'+str(a) + '='+str(sum))
    flg = 1
sum = d - c + b + a
if sum == 7 and flg== 0:
    print(str(d)+'-'+str(c)+'+'+str(b)+'+'+str(a) + '='+str(sum))
    flg = 1
sum = d - c + b - a
if sum == 7 and flg== 0:
    print(str(d)+'-'+str(c)+'+'+str(b)+'+'+str(a) + '='+str(sum))
    flg = 1
sum = d - c - b + a
if sum == 7 and flg== 0:
    print(str(d)+'-'+str(c)+'-'+str(b)+'+'+str(a) + '='+str(sum))
    flg = 1
sum = d - c - b - a
if sum == 7 and flg== 0:
    print(str(d)+'-'+str(c)+'-'+str(b)+'-'+str(a) + '='+str(sum))
    flg = 1

Submission status: Runtime Error

Solution code:
D, G = map(int, input().split())
PC = [tuple(map(int, input().split()))]

res = float("inf")
for bit in range(1 << D):
    sum = 0
    num = 0
    for i in range(D):
        if ((bit >> i) & 1):
            sum += (i + 1) * 100 * P[i] + C[i]
            num += P[i]
    if sum >= G:
        res = min(res, num)
    for i in range(D - 1, -1, -1):
        if ((bit >> i) & 1):
            continue
        for j in range(P[i] - 1):
            sum += (i + 1) * 100
            num + +
        if sum >= G:
            res = min(res, num)
            break
    print(res)

Submission status: Runtime Error

Solution code:
import numpy as np

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)

cnt = np.zeros(D,dtype=int)
P = np.array(P)
C = np.array(C)

ans = sum(P)
cnt_tar = 0

ind_list = np.arange(D)

if D < 11:
    for i in range(D):
        tar = i

        ind_list = list(range(D))
        ind_list.remove(tar)
        ind_list = np.array(ind_list)

        P_part = np.hstack((P[:tar], P[tar+1:]))
        C_part = np.hstack((C[:tar], C[tar+1:]))

        cnt_part = np.zeros(D-1,dtype=int)#[0 for _ in range(D-1)]
        point_part = np.zeros(D-1,dtype=int)#[0 for _ in range(D-1)]

        bit_list = np.ones(D-1,dtype=int)
        point_part_max = np.sum(((ind_list+1) * 100 * P_part + C_part)*bit_list)

        cnt_tar_min = max(0,(G - point_part_max)//((tar+1)*100))

        if cnt_tar_min > P[tar]:
            continue
        for cnt_tar in range(cnt_tar_min,P[tar]+1):
            point_base = cnt_tar*(tar+1)*100

            num_base   = cnt_tar + C[tar]*max(0,cnt_tar-P[tar] + 1)

            if point_base >= G or num_base >= ans:
                num = num_base
                ans = min(ans,num)
                break
            elif point_base + point_part_max >= G:

                for bit_seed in range(2**(D-1)):

                    s_bit = (format(bit_seed, '#011b'))[::-1]
                    bit_list = np.array(list(s_bit[:D-1]),dtype=int)

                    cnt_part = P_part*bit_list
                    num = num_base + np.sum(cnt_part)
                    if num > ans:
                        continue

                    point_part = cnt_part * (ind_list+1) * 100 + C_part*bit_list
                    point = point_base + np.sum(point_part)

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

    print(ans)
    exit()

for bit_seed in range(2**D):

    s_bit = (format(bit_seed, '#016b'))[::-1]
    bit_list = np.array(list(s_bit[:D]),dtype=int)

    cnt = P*bit_list
    num_base = np.sum(cnt)

    point_base_array = (P * (ind_list+1) * 100 + C) * bit_list
    point_base = np.sum(point_base_array)
#    print(point_base_array)

    if point_base >= G:
        num = num_base
        ans = min(ans,num)
    elif num_base > ans:
        continue
    else:
        for i,bit in enumerate(bit_list):
            if bit == 0:
                tar = i

        point_max = point_base + P[tar]*(tar+1)*100 + C[tar]
        if point_max >= G:

            tar_min = (G-point_base) // ((tar+1)*100)
            point = point_base + P[tar]*(tar+1)*100

            if point < G:
                tar_min += 1

            if tar_min < P[tar]:
                num = num_base + tar_min
            else:
                num = num_base + P[tar]
            ans = min(ans,num)

print(ans)

Submission status: Runtime Error

Solution code:
import numpy as np

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)

cnt = np.zeros(D,dtype=int)
P = np.array(P)
C = np.array(C)

ans = sum(P)
cnt_tar = 0

ind_list = np.arange(D)

if D < 10:
    for i in range(D):
        tar = i

        ind_list = list(range(D))
        ind_list.remove(tar)
        ind_list = np.array(ind_list)

        P_part = np.hstack((P[:tar], P[tar+1:]))
        C_part = np.hstack((C[:tar], C[tar+1:]))

        cnt_part = np.zeros(D-1,dtype=int)#[0 for _ in range(D-1)]
        point_part = np.zeros(D-1,dtype=int)#[0 for _ in range(D-1)]

        bit_list = np.ones(D-1,dtype=int)
        point_part_max = np.sum(((ind_list+1) * 100 * P_part + C_part)*bit_list)

        cnt_tar_min = max(0,(G - point_part_max)//((tar+1)*100))

        if cnt_tar_min > P[tar]:
            continue
        for cnt_tar in range(cnt_tar_min,P[tar]+1):
            point_base = cnt_tar*(tar+1)*100

            num_base   = cnt_tar + C[tar]*max(0,cnt_tar-P[tar] + 1)

            if point_base >= G or num_base >= ans:
                num = num_base
                ans = min(ans,num)
                break
            elif point_base + point_part_max >= G:

                for bit_seed in range(2**(D-1)):

                    s_bit = (format(bit_seed, '#011b'))[::-1]
                    bit_list = np.array(list(s_bit[:D-1]),dtype=int)

                    cnt_part = P_part*bit_list
                    num = num_base + np.sum(cnt_part)
                    if num > ans:
                        continue

                    point_part = cnt_part * (ind_list+1) * 100 + C_part*bit_list
                    point = point_base + np.sum(point_part)

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

    print(ans)
    exit()

for bit_seed in range(2**D):

    s_bit = (format(bit_seed, '#016b'))[::-1]
    bit_list = np.array(list(s_bit[:D]),dtype=int)

    cnt = P*bit_list
    num_base = np.sum(cnt)

    point_base_array = (P * (ind_list+1) * 100 + C) * bit_list
    point_base = np.sum(point_base_array)
#    print(point_base_array)

    if point_base >= G:
        num = num_base
        ans = min(ans,num)
    elif num_base > ans:
        continue
    else:
        for i,bit in enumerate(bit_list):
            if bit == 0:
                tar = i

        point_max = point_base + P[tar]*(tar+1)*100 + C[tar]
        if point_max >= G:

            tar_min = (G-point_base) // ((tar+1)*100)
            point = point_base + P[tar]*(tar+1)*100

            if point < G:
                tar_min += 1

            if tar_min < P[tar]:
                num = num_base + tar_min
            else:
                num = num_base + P[tar]
            ans = min(ans,num)

print(ans)

Submission status: Runtime Error

Solution code:
import numpy as np

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)

cnt = np.zeros(D,dtype=int)
P = np.array(P)
C = np.array(C)

ans = sum(P)
cnt_tar = 0

ind_list = np.arange(D)

if D < 8:
    for i in range(D):
        tar = i

        ind_list = list(range(D))
        ind_list.remove(tar)
        ind_list = np.array(ind_list)

        P_part = np.hstack((P[:tar], P[tar+1:]))
        C_part = np.hstack((C[:tar], C[tar+1:]))

        cnt_part = np.zeros(D-1,dtype=int)#[0 for _ in range(D-1)]
        point_part = np.zeros(D-1,dtype=int)#[0 for _ in range(D-1)]

        bit_list = np.ones(D-1,dtype=int)
        point_part_max = np.sum(((ind_list+1) * 100 * P_part + C_part)*bit_list)

        cnt_tar_min = max(0,(G - point_part_max)//((tar+1)*100))

        if cnt_tar_min > P[tar]:
            continue
        for cnt_tar in range(cnt_tar_min,P[tar]+1):
            point_base = cnt_tar*(tar+1)*100

            num_base   = cnt_tar + C[tar]*max(0,cnt_tar-P[tar] + 1)

            if point_base >= G or num_base >= ans:
                num = num_base
                ans = min(ans,num)
                break
            elif point_base + point_part_max >= G:

                for bit_seed in range(2**(D-1)):

                    s_bit = (format(bit_seed, '#011b'))[::-1]
                    bit_list = np.array(list(s_bit[:D-1]),dtype=int)

                    cnt_part = P_part*bit_list
                    num = num_base + np.sum(cnt_part)
                    if num > ans:
                        continue

                    point_part = cnt_part * (ind_list+1) * 100 + C_part*bit_list
                    point = point_base + np.sum(point_part)

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

    print(ans)
    exit()

for bit_seed in range(2**D):

    s_bit = (format(bit_seed, '#016b'))[::-1]
    bit_list = np.array(list(s_bit[:D]),dtype=int)

    cnt = P*bit_list
    num_base = np.sum(cnt)

    point_base_array = (P * (ind_list+1) * 100 + C) * bit_list
    point_base = np.sum(point_base_array)
#    print(point_base_array)

    if point_base >= G:
        num = num_base
        ans = min(ans,num)
    elif num_base > ans:
        continue
    else:
        for i,bit in enumerate(bit_list):
            if bit == 0:
                tar = i

        point_max = point_base + P[tar]*(tar+1)*100 + C[tar]
        if point_max >= G:

            tar_min = (G-point_base) // ((tar+1)*100)
            point = point_base + P[tar]*(tar+1)*100

            if point < G:
                tar_min += 1

            if tar_min < P[tar]:
                num = num_base + tar_min
            else:
                num = num_base + P[tar]
            ans = min(ans,num)

print(ans)

Submission status: Runtime Error

Solution code:
import numpy as np

D,G = map(int, input().split())
P = []
C = []

for i in range(D):
#    p,c = min(100,(i+1)*20),1000*(i+1)#map(int,input().split())
    p,c = map(int,input().split())
    P.append(p)
    C.append(c)

cnt = [0 for _ in range(D)]

ans = sum(P)
cnt_tar = 0

for i in range(D):
    tar = i

    ind_list = list(range(D))
    ind_list.remove(tar)
    ind_list = np.array(ind_list)

    P_part = np.array(P[:tar] + P[tar+1:])
    C_part = np.array(C[:tar] + C[tar+1:])

    cnt_part = np.zeros(D-1,dtype=int)#[0 for _ in range(D-1)]
    point_part = np.zeros(D-1,dtype=int)#[0 for _ in range(D-1)]

    bit_list = np.ones(D-1,dtype=int)
    point_part_max = np.sum(((ind_list+1) * 100 * P_part + C_part)*bit_list)

    cnt_tar_min = max(0,(G - point_part_max)//((tar+1)*100))

    if cnt_tar_min > P[tar]:
        continue
    for cnt_tar in range(cnt_tar_min,P[tar]+1):
        point_base = cnt_tar*(tar+1)*100

        num_base   = cnt_tar + C[tar]*max(0,cnt_tar-P[tar] + 1)

        if point_base >= G or num_base >= ans:
            num = num_base
            ans = min(ans,num)
            break
        elif point_base + point_part_max >= G:

            for bit_seed in range(2**(D-1)):

                s_bit = (format(bit_seed, '#011b'))[::-1]
                bit_list = np.array(list(s_bit[:D-1]),dtype=int)

                cnt_part = P_part*bit_list
                num = num_base + np.sum(cnt_part)
                if num > ans:
                    continue

                point_part = cnt_part * (ind_list+1) * 100 + C_part*bit_list
                point = point_base + np.sum(point_part)

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

print(ans)
#     while cnt_part != P_part:
#     ind = 0

#     cnt = kuriage(cnt,P,ind,tar,C,G)
#     print(cnt)
#     if cnt[tar] == -1:
#         cnt = [0 for _ in range(D)]
#         tar += 1

#     if point_over(cnt,P,C,G) and ans > sum(cnt):
#         ans = min(ans, sum(cnt))
# #            print(ans)

# print(ans)


# def kuriage(cnt,P,ind,tar,C,G):

#     if cnt[ind] == 0:
#         cnt[ind:ind+1] = P[ind:ind+1]
#     elif cnt[ind] == P[ind]:
#         if 0 in cnt[:tar] and 0 in cnt[tar+1:]:
#             if ind+1 == tar:
#                 kuriage(cnt,P,ind+2, tar, C, G)
#             else:
#                 kuriage(cnt,P,ind+1, tar, C, G)
#         else:
#             if C[tar] != P[tar]:
#                 C[tar] = C[tar] + 1
#             else:
#                 C[tar] = -1
#     return cnt
# def point_over(cnt,P,C,G):
#     point = 0
#     for i in range(len(P)):
#         point += cnt[i]*100*(i+1)
#         if cnt[i] == P[i]:
#             point += C[i]

#         if point >= G:
#             return True

#     if point < G:
#         return False

# def point(cnt,P,C):
#     point = 0

#     for i,cnt_s in enumerate(cnt):
#         print(cnt_s,'ok')
#         if cnt_s == 0:
#             point += 0
#         else:
#             point += cnt[i]*100*(i+1) + C[i]
#     return point