Submission #1339948

#TimeUsernameProblemLanguageResultExecution timeMemory
1339948ghassanhasanBank (IZhO14_bank)C++20
100 / 100
108 ms4392 KiB
#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>

using namespace std;

int N, M;
int a[21];
int b[21];
vector<int> masks_by_sum[1001]; // Only need up to 1000 as per constraints
int memo[1 << 20]; // Bitmask to store which persons (p_idx) failed for a banknote mask

bool solve(int p_idx, int b_mask) {
    // If we have satisfied all N people, we are done
    if (p_idx == N) return true;
    
    // If this specific combination of banknotes has already failed for this person, skip
    if (memo[b_mask] & (1 << p_idx)) return false;

    int target = a[p_idx];
    // Try all precalculated masks that sum up to the current person's salary
    for (int m : masks_by_sum[target]) {
        // Check if these banknotes are still available (not in b_mask)
        if (!(b_mask & m)) {
            if (solve(p_idx + 1, b_mask | m)) return true;
        }
    }

    // Mark this state as failed
    memo[b_mask] |= (1 << p_idx);
    return false;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    if (!(cin >> N >> M)) return 0;

    long long sum_a = 0;
    for (int i = 0; i < N; ++i) {
        cin >> a[i];
        sum_a += a[i];
    }
    
    long long sum_b = 0;
    for (int i = 0; i < M; ++i) {
        cin >> b[i];
        sum_b += b[i];
    }

    // Basic feasibility check
    if (sum_a > sum_b) {
        cout << "NO" << endl;
        return 0;
    }

    // Sorting salaries descending helps prune the search tree significantly
    sort(a, a + N, greater<int>());

    // Precalculate all banknote subset sums that match any a_i
    bool needed[1001] = {false};
    for(int i=0; i<N; ++i) needed[a[i]] = true;

    for (int i = 0; i < (1 << M); ++i) {
        int current_sum = 0;
        for (int j = 0; j < M; ++j) {
            if (i & (1 << j)) {
                current_sum += b[j];
                if (current_sum > 1000) break; 
            }
        }
        if (current_sum <= 1000 && needed[current_sum]) {
            masks_by_sum[current_sum].push_back(i);
        }
    }

    if (solve(0, 0)) cout << "YES" << endl;
    else cout << "NO" << endl;

    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...