見出し画像

アルゴリズム道中記〜20240409〜

#include <bits/stdc++.h>
#define print(x) cout << x << endl;
#define rep(i, s, n) for (long long i = s; i < (long long)(n); i++)
using namespace std;
using ll = long long;

int main() {
  ll N, S;
  cin >> N >> S;
  vector<ll> A(N+1);
  rep (i, 1, N+1) 
    cin >> A[i];
  vector<vector<bool>> dp(N+1, vector<bool>(S+1));
  dp[0][0] = true;
  rep (i, 1, S+1) 
    dp[0][i] = false;
 rep (i, 1, N+1)
  {
    rep (k, 0, S+1)
    {
      if (k < A[i])
      {
        if (dp[i-1][k]) dp[i][k] = true;
        else dp[i][k] = false;
      }
      if (k >= A[i])
      {
        if (dp[i-1][k] || dp[i-1][k-A[i]]) dp[i][k] = true;
        else dp[i][k] = false;
      }
    }
  }
  if (dp[N][S]) {print("Yes");}
  else print("No");
}

部分和問題です。DPは、二次元になると途端に難しくなります… ほとんど写経に近いです。

なんとなく考え方はわかってきたかもしれません。i-1で採用された数は、そのまま採用されるところなどは、自然だと雰囲気で理解しました。DPテーブルのインデックスをそのまま値のメモとして使うのが、なんだか新鮮です。

この記事が気に入ったらサポートをしてみませんか?