クルトンのプログラミング教室

Pythonの使い方やPythonを使った競技プログラミングの解法などを解説しています。

Pythonで理解する蟻本「2-3 重複組み合わせ」(p.67)

この記事は「プログラミングコンテストチャレンジブック第2版」(蟻本)の
「2-3 重複組み合わせ」(p.67)
のコードをPythonで書き直したものとなっています。

入力

n\,m\\a_1\,…\,a_n\\M

入力例



3 3
1 2 3
10000


解答

MAX_N = 1000
MAX_M = 1000

# 入力
n, m = map(int,input().split())
a = list(map(int,input().split()))
M = int(input())

dp = [[0] * (MAX_M + 1) for _ in range(MAX_N + 1)]    # DPテーブル

# 1つも選ばない方法は常に一通り
for i in range(n + 1):
    dp[i][0] = 1
for i in range(n):
    for j in range(1, m + 1):
        if j - 1 - a[i] >= 0:
            # Pythonでは負の数でも直接余りを求められる(Mを足さなくてもよい)
            dp[i + 1][j] = (dp[i + 1][j - 1] + dp[i][j] - dp[i][j - 1 - a[i]]) % M
        else:
            dp[i + 1][j] = (dp[i + 1][j - 1] + dp[i][j]) % M
print(dp[n][m])