Buggy python submission (verdict: Time Limit Exceeded):
D, G = list(map(int, input().split(' ')))
p_list = list()
c_list = list()
for _ in range(D):
    p, c = list(map(int, input().split(' ')))
    p_list.append(p)
    c_list.append(c)
num_prob_list = [0] * D
min_prob_num_sum = sum(p_list)


def dfs(prob_index=-1, prob_num=0, current_prob_num_sum=0, current_score=0):
    """
    Returns whether score >= G with local minimum of problems.
    """
    global min_prob_num_sum
    if prob_index >= 0:
        current_prob_num_sum += prob_num
        if current_prob_num_sum >= min_prob_num_sum:
            return False
        num_prob_list[prob_index] = prob_num
        current_score += 100 * (prob_index + 1) * prob_num
        if prob_num == p_list[prob_index]:
            current_score += c_list[prob_index]
        if current_score >= G:
            min_prob_num_sum = current_prob_num_sum
            # print(num_prob_list[:(prob_index + 1)])
            # print(current_score)
            return True
    next_prob_index = prob_index + 1
    if next_prob_index > D - 1:
        return False
    for next_prob_num in range(p_list[next_prob_index] + 1):
        if dfs(next_prob_index, next_prob_num, current_prob_num_sum, current_score):
            break


dfs()
print(min_prob_num_sum)

Fixed submission:
import itertools
import math
D, G = list(map(int, input().split(' ')))
p_list = list()
c_list = list()
for _ in range(D):
    p, c = list(map(int, input().split(' ')))
    p_list.append(p)
    c_list.append(c)
ans = sum(p_list)
pattern_list = itertools.product([0, 1], repeat=D)
for pattern in pattern_list:
    score = 0
    prob_num = 0
    # Solve all problems with bit `1`
    score += sum([bit * (100 * (index + 1) * p_list[index] + c_list[index]) for index, bit in enumerate(pattern)])
    prob_num += sum([bit * p_list[index] for index, bit in enumerate(pattern)])
    # Solve problems partially with bit `0'
    if score < G:
        for index in range(D - 1, -1, -1):
            if pattern[index] == 1:
                # skip because these cases are already counted
                continue
            required_num = math.ceil((G - score) / (100 * (index + 1)))
            sol_num = min([p_list[index] - 1, required_num])
            score += 100 * (index + 1) * sol_num
            prob_num += sol_num
            if score >= G:
                break
    # update answer
    if score >= G:
        ans = min([ans, prob_num])
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
D, G = list(map(int, input().split(' ')))
p_list = list()
c_list = list()
for _ in range(D):
    p, c = list(map(int, input().split(' ')))
    p_list.append(p)
    c_list.append(c)
num_prob_list = [0] * D
min_prob_num_sum = sum(p_list)


def dfs(prob_index=-1, prob_num=0, current_score=0):
    """
    Returns whether score >= G.
    """
    global min_prob_num_sum
    if prob_index >= 0:
        num_prob_list[prob_index] = prob_num
        current_score += 100 * (prob_index + 1) * prob_num
        if prob_num == p_list[prob_index]:
            current_score += c_list[prob_index]
        if current_score >= G:
            prob_num_sum = sum(num_prob_list[:(prob_index + 1)])
            if min_prob_num_sum > prob_num_sum:
                min_prob_num_sum = prob_num_sum
                # print(num_prob_list[:(prob_index + 1)])
                # print(current_score)
            return True
    next_prob_index = prob_index + 1
    if next_prob_index > D - 1:
        return False
    for next_prob_num in range(p_list[next_prob_index] + 1):
        if dfs(next_prob_index, next_prob_num, current_score):
            break


dfs()
print(min_prob_num_sum)

Fixed submission:
import itertools
import math
D, G = list(map(int, input().split(' ')))
p_list = list()
c_list = list()
for _ in range(D):
    p, c = list(map(int, input().split(' ')))
    p_list.append(p)
    c_list.append(c)
ans = sum(p_list)
pattern_list = itertools.product([0, 1], repeat=D)
for pattern in pattern_list:
    score = 0
    prob_num = 0
    # Solve all problems with bit `1`
    score += sum([bit * (100 * (index + 1) * p_list[index] + c_list[index]) for index, bit in enumerate(pattern)])
    prob_num += sum([bit * p_list[index] for index, bit in enumerate(pattern)])
    # Solve problems partially with bit `0'
    if score < G:
        for index in range(D - 1, -1, -1):
            if pattern[index] == 1:
                # skip because these cases are already counted
                continue
            required_num = math.ceil((G - score) / (100 * (index + 1)))
            sol_num = min([p_list[index] - 1, required_num])
            score += 100 * (index + 1) * sol_num
            prob_num += sol_num
            if score >= G:
                break
    # update answer
    if score >= G:
        ans = min([ans, prob_num])
print(ans)