yokobuttonの不定期で競技プログラミングをするブログ

不定期で解けた競技プログラミングコンテストの問題を載せています。

パナソニックグループプログラミングコンテスト2022(AtCoder Beginner Contest 251) B - At Most 3 (Judge ver.)

問題の要約
おもり1,おもり2,...,おもりNのN個のおもりがある。おもりiの重さはAi。
以下の条件を満たす正整数nを良い整数とよぶ。
 ・3個以下の異なるおもりを自由に選んで、選んだおもりの重さの和をnにすることができる。
W以下の正整数のうち、良い整数は何個あるか?

制約
1<=N<=300
1<=W<=10^6
1<=Ai<=10^6

入力
N W
A1 A2 ... AN

考え方
1,おもりの重さをvector<int>Aで管理する。
2,良い整数をvector<bool>SUMで0からWまで管理する。最初は全部false。
3,3個以下の異なるおもりを選ぶことができればよいので、3重のfor文を考え、良い整数をtrueにしていく。
 おもりが1個の時はfor文の1つ目、おもりが2個の時はfor文の1つ目と2つ目、おもりが3個の時はfor文の1つ目と2つ目と3つ目に相当する。
 おもりの重さの合計がW以下のものしか扱わないことに注意する。
4,SUMを0からWまでを操作してtrueのものだけをカウントする。

実際のプログラム
#include<iostream>
#include<vector>

using namespace std;

int main(){
  int N,W;
  cin >> N >> W;
  
  vector<bool> SUM(W+1,false);
  
  vector<int> A(N);
  for(int i = 0; i < N; ++i){
    cin >> A[i];
  }
  
  for(int i = 0; i < N; ++i){
    if(A[i] <= W){
      SUM[A[i]] = true;
    }
    for(int j = i+1; j < N; ++j){
      if(A[i]+A[j] <= W){
        SUM[A[i]+A[j]] = true;
      }
      for(int k = j+1; k < N; ++k){
        if(A[i]+A[j]+A[k] <= W){
          SUM[A[i]+A[j]+A[k]] = true;
        }
      }
    }
  }
  
  int ans = 0;
  for(int i = 0; i < W+1; ++i){
    if(SUM[i]){
      ++ans;
    }
  }
  
  cout << ans << endl;
  
  return 0;
}