#include <iostream> #include <set> #include <climits> #include <algorithm> #include <stack> using weight = int64_t; using weights = std::multiset<int64_t>; using weight_iter = weights::const_iterator; struct Frame { const weight pike; const int eaten; const weight_iter start_at; Frame(weight pike, int eaten, weight_iter start_at) : pike(pike), eaten(eaten), start_at(start_at) {} }; weight_iter next(const weight_iter iter) { weight_iter copy = weight_iter(iter); ++copy; return copy; } int min_sprats_rec(weight pike, weight pike_target, int eaten, int min_eaten, const weights& sprats, weight_iter start_at) { if (pike >= pike_target) { return std::min(eaten, min_eaten); } for (weight_iter it = start_at; it != sprats.end(); it++) { weight sprat = *it; if (sprat < pike) { min_eaten = min_sprats_rec(pike + sprat, pike_target, eaten + 1, min_eaten, sprats, next(it)); } } return min_eaten; } int min_sprats_iter(weight pike_start, weight pike_target, const weights& sprats) { int min_eaten = INT_MAX; std::stack<Frame> frames = std::stack<Frame>(); frames.push(Frame(pike_start, 0, sprats.begin())); while (!frames.empty()) { Frame f = frames.top(); frames.pop(); if (f.pike >= pike_target) { min_eaten = std::min(f.eaten, min_eaten); } else { for (weight_iter it = f.start_at; it != sprats.end(); it++) { weight sprat = *it; if (sprat < f.pike) { frames.push(Frame(f.pike + sprat, f.eaten + 1, next(it))); } } } } return min_eaten; } int main() { int sprat_count; std::cin >> sprat_count; weights sprats = weights(); for (int s = 0; s < sprat_count; s++) { weight sprat; std::cin >> sprat; sprats.insert(sprat); } int event_count; std::cin >> event_count; for (int e = 0; e < event_count; e++) { int event; std::cin >> event; if (event == 1) { weight pike, pike_target; std::cin >> pike >> pike_target; int eaten = min_sprats_iter(pike, pike_target, sprats); std::cout << (eaten == INT_MAX? -1 : eaten) << std::endl; } else if (event == 2) { weight sprat; std::cin >> sprat; sprats.insert(sprat); } else if (event == 3) { weight sprat; std::cin >> sprat; sprats.erase(sprats.lower_bound(sprat)); } } return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | #include <iostream> #include <set> #include <climits> #include <algorithm> #include <stack> using weight = int64_t; using weights = std::multiset<int64_t>; using weight_iter = weights::const_iterator; struct Frame { const weight pike; const int eaten; const weight_iter start_at; Frame(weight pike, int eaten, weight_iter start_at) : pike(pike), eaten(eaten), start_at(start_at) {} }; weight_iter next(const weight_iter iter) { weight_iter copy = weight_iter(iter); ++copy; return copy; } int min_sprats_rec(weight pike, weight pike_target, int eaten, int min_eaten, const weights& sprats, weight_iter start_at) { if (pike >= pike_target) { return std::min(eaten, min_eaten); } for (weight_iter it = start_at; it != sprats.end(); it++) { weight sprat = *it; if (sprat < pike) { min_eaten = min_sprats_rec(pike + sprat, pike_target, eaten + 1, min_eaten, sprats, next(it)); } } return min_eaten; } int min_sprats_iter(weight pike_start, weight pike_target, const weights& sprats) { int min_eaten = INT_MAX; std::stack<Frame> frames = std::stack<Frame>(); frames.push(Frame(pike_start, 0, sprats.begin())); while (!frames.empty()) { Frame f = frames.top(); frames.pop(); if (f.pike >= pike_target) { min_eaten = std::min(f.eaten, min_eaten); } else { for (weight_iter it = f.start_at; it != sprats.end(); it++) { weight sprat = *it; if (sprat < f.pike) { frames.push(Frame(f.pike + sprat, f.eaten + 1, next(it))); } } } } return min_eaten; } int main() { int sprat_count; std::cin >> sprat_count; weights sprats = weights(); for (int s = 0; s < sprat_count; s++) { weight sprat; std::cin >> sprat; sprats.insert(sprat); } int event_count; std::cin >> event_count; for (int e = 0; e < event_count; e++) { int event; std::cin >> event; if (event == 1) { weight pike, pike_target; std::cin >> pike >> pike_target; int eaten = min_sprats_iter(pike, pike_target, sprats); std::cout << (eaten == INT_MAX? -1 : eaten) << std::endl; } else if (event == 2) { weight sprat; std::cin >> sprat; sprats.insert(sprat); } else if (event == 3) { weight sprat; std::cin >> sprat; sprats.erase(sprats.lower_bound(sprat)); } } return 0; } |