Typical DP Contest A - コンテスト
問題
問題概要
N問の問題があるコンテストがあり、i問目(1-index)の問題の配点は
p[i-1]点である。この問題の中から何問か解き、解いた問題の配点の合計が得点となる。このコンテストの得点は何通り考えられるか。
解法
dp[i][j] : i番目まで見て点数がjになる通り数
0≦i≦N、0≦j≦Σp[i-1]
dp[i][j]=dp[i-1][j]+dp[i-1][j-p[i-1]]
ただしj-p[i-1]<0の時は
dp[i][j]=dp[i-1][j]
i=0かつj=0のとき
dp[i][j]=1
i=0かつj≠0のとき
dp[i][j]=0
答えはi=Nのときのj≠0となる個数
ソースコード
signed main() { int N; cin >> N; vector<int>p(N); int Sp = 0; rep(i, N) { cin >> p[i]; Sp += p[i]; } vector<vector<int>>dp(N + 1, vector<int>(Sp + 1)); rep(i, N + 1) { rep(j, Sp + 1) { if (i == 0 && j == 0) { dp[i][j] = 1; } else if (i == 0 && j != 0) { dp[i][j] = 0; } else if (j - p[i - 1] < 0) { dp[i][j] = dp[i - 1][j]; } else { dp[i][j] = dp[i - 1][j] + dp[i - 1][j - p[i - 1]]; } } } int ans = 0; rep(i, N + 1) { rep(j, Sp + 1) { if (i == N) { ans += dp[i][j] != 0; } } } cout << ans << endl; }