けんちょんの競プロ精進記録

競プロの精進記録や小ネタを書いていきます

鉄則本 A18 - Subset Sum (3Q, ★3)

部分和問題。鉄則本の問題なので、コードのみ。

問題概要

 N 個の整数  A_{1}, A_{2}, \dots, A_{N} からいくつか選んで、総和を  S にすることが可能かどうかを判定せよ。

制約

  •  1 \le N \le 60
  •  1 \le S, A_{i} \le 10^{4}

コード

#include <bits/stdc++.h>
using namespace std;

int main() {
    int N, S;
    cin >> N >> S;
    vector<int> A(N);
    for (int i = 0; i < N; i++) cin >> A[i];

    vector<vector<bool>> dp(N+1, vector<bool>(S+1, false));
    dp[0][0] = true;
    for (int i = 0; i < N; i++) {
        for (int s = 0; s <= S; s++) {
            if (!dp[i][s]) continue;
            dp[i+1][s] = true;
            if (s+A[i] <= S) dp[i+1][s+A[i]] = true;
        }
    }
    cout << (dp[N][S] ? "Yes" : "No") << endl;
}