Submission #1370166

#TimeUsernameProblemLanguageResultExecution timeMemory
1370166c12Bank (IZhO14_bank)C++20
100 / 100
63 ms8516 KiB
#include <bits/stdc++.h>
using namespace std;

int main() {
    // Optimize standard I/O operations for performance
    ios::sync_with_stdio(0); cin.tie(0);

    int n, m;
    if (!(cin >> n >> m)) return 0;

    vector<int> people(n), money(m);
    for (int i = 0; i < n; i++) cin >> people[i];
    for (int i = 0; i < m; i++) cin >> money[i];

    // dp[mask] stores a pair:
    // .first  = maximum number of people fully paid off
    // .second = money accumulated toward the NEXT person's salary
    // We initialize with {-1, -1} to flag unreachable states.
    vector<pair<int, int>> dp(1 << m, {-1, -1});
    
    // Base case: 0 banknotes used, 0 people paid, 0 money accumulated
    dp[0] = {0, 0};

    for (int mask = 0; mask < (1 << m); mask++) {
        // Skip states that cannot be reached
        if (dp[mask].first == -1) continue;

        int p_paid = dp[mask].first;
        int curr_sum = dp[mask].second;

        // If we have successfully paid all N people, we can stop immediately
        if (p_paid == n) {
            cout << "YES\n";
            return 0;
        }

        // Try adding each unused banknote to the current mask
        for (int i = 0; i < m; i++) {
            // Check if the i-th bit is OFF (banknote 'i' is not used yet)
            if (!(mask & (1 << i))) { 
                int nmask = mask | (1 << i);       // Create the new state mask
                int nsum = curr_sum + money[i];    // Add the banknote's value

                // Case 1: The accumulated money is still less than the current person's salary
                if (nsum < people[p_paid]) {
                    dp[nmask] = max(dp[nmask], {p_paid, nsum});
                } 
                // Case 2: The accumulated money EXACTLY matches the current person's salary
                else if (nsum == people[p_paid]) {
                    // Increment people paid, reset the accumulated money to 0
                    dp[nmask] = max(dp[nmask], {p_paid + 1, 0});
                }
                // If nsum > people[p_paid], the banknote is too big. We do nothing (invalid transition).
            }
        }
    }

    // Final check: Iterated through all combinations but couldn't pay everyone
    cout << "NO\n";
    return 0;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...