Language: C++

#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>

using namespace std;

//cardsのうちK - num以上K - 1以下の和をもつ部分集合Sが作れるか//
//をDPで判定する関数//
bool search_set(vector<int> cards, int K, int num){
        //exist[i][j]はcardsのi枚目まで使って合計jとなる部分集合を作れるかどうか//
        bool exist[cards.size()][K];

        unsigned int i, j;

        //初期化//
        for(i = 1; i < K; i++){
                if(cards[0] == i)
                        exist[0][i] = true;
                else
                        exist[0][i] = false;
        }

        //条件を満たす集合が見つかったかのフラグ//
        bool find = false;

        //サイズが1の場合は別に処理//
        if(cards.size() == 1){
                for(int k = K - num; k < K; k++){
                        if(exist[0][k] = true){
                                find = true;
                                break;
                        }
                }

                return true;
        }

        //それ以外はDPmatrixを埋めていく//
        //exist[i][j](K - num <= j <= K - 1)がtrueになるまでループ//
        for(i = 1; i < cards.size(); i++){
                //K - num <= j <= K - 1がtrueになったかどうかのフラグ//
                bool ok;
                for(j = 1; j < K; j++){
                        if(exist[i - 1][j] == true){
                                exist[i][j] = true;
                                if(j + cards[i] < K)
                                        exist[i][j + cards[i]] = true;
                        }
                        if(cards[i] == j)
                                exist[i][j] = true;

                        if(j >= K - num && j <= K - 1 && exist[i][j] = true){
                                ok = true;
                                break;
                        }
                }

                //okがtrueなら見つかったので終了//
                if(ok){
                        find = true;
                        break;
                }
        }

        return find;

}


int main(){
        //カードの枚数N, 目標とする和K//
        int N, K, i;

        cin >> N >> K;

        //改行文字が入らないように1文字飛ばす//
        cin.ignore();
        //N個のカードの数字が格納されたvector cards//
        string str;
        vector<int> cards;
        if(N > 1){
                for(i = 0; i < N - 1; i++){
                        getline(cin, str, ' ');
                        cards.push_back(stoi(str));
                }
        }
        getline(cin, str);
        cards.push_back(stoi(str));

        //cardsをソートする//
        sort(cards.begin(), cards.end());
       //K以下の数字を持つカードの和sumをとる//
        long int sum = 0;
        for(i = 0; i < N; i++){
                if(cards[i] < K)
                        sum += cards[i];
                else
                        break;
        }

        //K以上の数のカードはそれ1枚の集合で必要となり//
        //他のカードと組んでギリギリの集合を作らないので消去//
        cards.erase(cards.begin() + i, cards.end());

        //もしsumがKより小さいならK以下のカードはすべて不要//
        if(sum < K)
                cout << i << endl;

        //sumがKに等しいかすべてのカードがK以上ならばどれが抜けてもダメなので全て必要//
        else if(sum == K || i == 0)
                cout << 0 << endl;

        //それ以外は大きい方から1枚ずつ必要か判断//
        else{

                //カードaの数字Naとすると、S < K && S + Na >= Kなる集合が見つかれば//
                //aは必要で、なければ不必要//
                //大きい方から見て初めて不要なカードが出た時点で//
                //それ以下の数のカードはすべて不要//
                vector<int> n_cards;
                for(i = cards.size() - 1; i >= 0; i--){
                        //n_cardsにcardsをコピー//
                        copy(cards.begin(), cards.end(), back_inserter(n_cards));
                        //集合からcards[i]を消去//
                        n_cards.erase(n_cards.begin() + i);
                        //search_setはcardsのうちK - cards[i] <= S <= K - 1//
                        //を満たす部分集合Sが存在するか確かめる関数//
                        //Sが見つかったら同じ大きさの数のカードは飛ばしてループ続行//
                        if(search_set(n_cards, K, cards[i])){
                                while(i >= 1){
                                        if(cards[i] == cards[i - 1])
                                                i--;
                                        else
                                                break;
                                }
                        }

                        //falseならばその場でbreak//
                        else
                                break;
                        n_cards.clear();
                }

                //iは不要なカードのindexで止まっているので+1する//
                cout << i + 1 << endl;
        }

        return 0;
}


Compiler output:
a.cc: In function 'bool search_set(std::vector<int>, int, int)':
a.cc:53:55: error: lvalue required as left operand of assignment
   53 |                         if(j >= K - num && j <= K - 1 && exist[i][j] = true){
      |                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~