Problem p03290 (python)

Fixed submission:
import numpy as np

D, G, *pc = map(int, open(0).read().split())
pc = list(zip(*[iter(pc)]*2))
p, c = np.array([]), np.array([])
for (x,y) in pc:
    p = np.append(p, x)
    c = np.append(c, y)
    
import numpy as np
import math

base_points = np.array([i*100 for i in range(1, D+1)])

ans = []

for i in range(2**D):
    bit_flag = np.array(list(map(int, format(i, '0%db' %D))))
    points = sum(bit_flag * (c + p*base_points))
    solved_num = sum(bit_flag * p)
    
    if points >= G:
        ans.append(solved_num)

    else:
        remained = G - points
        remained_problems = sorted((bit_flag==False) * np.array(range(1, D+1)), reverse=True)
        i = 0

        while True:
            if remained <= 0:
                break
                
            highest_p = remained_problems[i]

            if math.ceil(remained / (highest_p * 100)) <= p[highest_p - 1]:
                solved_num += math.ceil(remained / (highest_p * 100))
                remained -= (math.ceil(remained / (highest_p * 100)) * highest_p * 100)
            else:
                solved_num += p[highest_p - 1]
                remained -= (highest_p * 100 * p[highest_p - 1] + c[highest_p - 1])
                i += 1

        ans.append(solved_num)
        
print(int(min(ans)))

Buggy submission (verdict: Runtime Error):
import numpy as np

D, G, *pc = map(int, open(0).read().split())
pc = list(zip(*[iter(pc)]*2))
p, c = np.array([]), np.array([])
for (x,y) in pc:
    p = np.append(p, x)
    c = np.append(c, y)
    
import numpy as np
import math

base_points = np.array([i*100 for i in range(1, D+1)])

ans = []

for i in range(2**D):
    bit_flag = np.array(list(map(int, format(i, '0%db' %D))))
    
    points = sum(bit_flag * (c + p*base_points))
    solved_num = sum(bit_flag * p)
    
    if points >= G:
        ans.append(solved_num)

    else:
        achieved = False
        remained = G - points
        remained_problems = sorted((bit_flag==False) * np.array(range(1, D+1)), reverse=True)
        i = 0

        while not achieved:
            highest_p = remained_problems[i]
            if remained <= 0:
                achieved = True
            elif math.ceil(remained / (highest_p * 100)) <= p[highest_p - 1]:
                solved_num += math.ceil(remained / (highest_p * 100))
                remained -= (math.ceil(remained / (highest_p * 100)) * highest_p * 100)
            else:
                solved_num += p[highest_p - 1]
                remained -= (highest_p * 100 * p[highest_p - 1] + c[highest_p - 1])
                i += 1

        ans.append(solved_num)
        
print(int(min(ans)))

Buggy submission (verdict: Runtime Error):
D, G, *pc = map(int, open(0).read().split())
pc = list(zip(*[iter(pc)]*2))

# 全完一つで達成できるケース

total_points = []
for i in range(D):
    total_points.append(pc[i][0] * (i+1) * 100 + pc[i][1])
    
ans_list = [i[0] for i, x in zip(pc, total_points) if x >= G]

# 完答ボーナスを含め、最も効率の良い問題から解くケース
efficient_order = sorted(list(zip([x/y for x,(y,z) in list(zip(total_points, pc))], range(1, D+1))), reverse = True)

achieved = False
remained = G
highest_p = D

ans_other = 0

for _, i in efficient_order:
        if remained <= 0:
            break
        elif math.ceil(remained / (i * 100)) <= pc[i - 1][0]:
            ans_other += math.ceil(remained / (i * 100))
            remained -= (math.ceil(remained / (i * 100)) * i * 100)
        else:
            ans_other += pc[i - 1][0]
            remained -= (i * 100 * pc[i - 1][0] + pc[i - 1][1])

ans_list.append(ans_other)

print(min(ans_list))

Buggy submission (verdict: Runtime Error):
D, G, *pc = map(int, open(0).read().split())
pc = list(zip(*[iter(pc)]*2))

total_points = []
for i in range(D):
    total_points.append(pc[i][0] * (i+1) * 100 + pc[i][1])
    
ans_list = [i[0] for i, x in zip(pc, total_points) if x >= G]

import math

achieved = False
remained = G
highest_p = D

ans_other = 0

while not achieved:
    if math.ceil(remained / (highest_p * 100)) <= pc[highest_p - 1][0]:
        ans_other += math.ceil(remained / (highest_p * 100))
        achieved = True
    else:
        ans_other += pc[highest_p - 1][0]
        remained -= (highest_p * 100 * pc[highest_p - 1][0] + pc[highest_p - 1][1])
        highest_p -= 1
        
ans_list.append(ans_other)

print(min(ans_list))