アルゴリズム道中記〜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テーブルのインデックスをそのまま値のメモとして使うのが、なんだか新鮮です。
この記事が気に入ったらサポートをしてみませんか?