Submission #1286585

#TimeUsernameProblemLanguageResultExecution timeMemory
1286585harryleee은행 (IZhO14_bank)C++20
100 / 100
227 ms9704 KiB
#include <bits/stdc++.h>
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, m;
    if (!(cin >> n >> m)) return 0;
    vector<int> a(n), b(m);
    for (int i = 0; i < n; ++i) cin >> a[i];
    for (int i = 0; i < m; ++i) cin >> b[i];

    // trace[sum] = list of masks (subsets of b) whose sum == sum
    const int MAXSUM = 1000;
    vector<vector<int>> trace(MAXSUM + 1);
    int ALL = (1 << m);
    for (int mask = 1; mask < (1 << m); ++mask){
        int sum = 0;
        // compute sum of this mask
        for (int i = 0; i < m; ++i) if (mask & (1 << i)) sum += b[i];
        if (sum <= MAXSUM) trace[sum].push_back(mask);
    }

    // Edge: if any a[i] > MAXSUM, then trace[a[i]] empty and impossible
    for (int i = 0; i < n; ++i){
        if (a[i] > MAXSUM) {
            cout << "NO\n";
            return 0;
        }
    }

    // marked_prev[x] == 1 means mask x is true in dp for previous i
    // marked_next is for building dp for current i
    vector<char> marked_prev(ALL, 0), marked_next(ALL, 0);
    vector<int> prev_masks, next_masks;

    // initialize for i = 0
    for (int mask1 : trace[a[0]]){
        if (!marked_prev[mask1]){
            marked_prev[mask1] = 1;
            prev_masks.push_back(mask1);
        }
    }

    if (prev_masks.empty()){
        cout << "NO\n";
        return 0;
    }

    // iterate persons 1..n-1
    for (int i = 1; i < n; ++i){
        next_masks.clear();
        fill(marked_next.begin(), marked_next.end(), 0); // reset

        // for each mask1 that can serve person i
        for (int mask1 : trace[a[i]]){
            // combine with every previously achievable mask_prev
            for (int mask_prev : prev_masks){
                if ((mask_prev & mask1) == 0){
                    int new_mask = mask_prev | mask1;
                    if (!marked_next[new_mask]){
                        marked_next[new_mask] = 1;
                        next_masks.push_back(new_mask);
                    }
                }
            }
        }

        if (next_masks.empty()){
            cout << "NO\n";
            return 0;
        }

        // move next -> prev for next iteration
        prev_masks.swap(next_masks);
        marked_prev.swap(marked_next);
    }

    // nếu tồn tại ít nhất 1 mask sau người cuối thì thành công
    if (!prev_masks.empty()) cout << "YES\n";
    else cout << "NO\n";
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...