#include <set> #include <stdio.h> #define MAX_LENGTH 10000000 struct Solution { long long int energy; int length; bool operator<(const Solution &s) const { if (energy != s.energy) return energy < s.energy; else return length < s.length; } }; using Solutions = std::set<Solution>; void insert(Solutions &solutions, const Solution solution) { auto is_bad_element = [&solution](const Solution &s) { if (s.energy < solution.energy) return s.length >= solution.length; else if (s.energy == solution.energy) return s.length > solution.length; return false; }; auto it = solutions.lower_bound(solution); if (it != solutions.end()) { if (it->length > solution.length) { it = solutions.insert(it, solution); auto remove_from = it; while (remove_from != solutions.begin() && is_bad_element(*std::prev(remove_from))) remove_from--; if (it != remove_from) solutions.erase(remove_from, it); } } else { it = solutions.insert(it, solution); } } void add(Solutions &solutions, int energy, int distance, long long int &sum_energy, int &sum_distance) { auto it = solutions.lower_bound(Solution({-sum_energy, 0})); if (it != solutions.end()) insert(solutions, {-sum_energy, it->length - distance}); sum_energy += energy; sum_distance += distance; } int get_result(const Solutions &solutions, const long long int &sum_energy, const int &sum_distance) { int best_length = MAX_LENGTH; for (const auto &data : solutions) if (data.energy + sum_energy >= 0) best_length = std::min(best_length, data.length + sum_distance); if (best_length != MAX_LENGTH) return best_length; else return -1; } int main() { int n, energy, distance = 0, sum_distance = 0; long long int sum_energy = 0; Solutions solutions; scanf("%d", &n); for (int i = 1; i <= n; ++i) { scanf("%d", &energy); distance++; if (energy != 0) { if (solutions.empty()) { solutions.insert({0, 0}); sum_energy += energy; } else add(solutions, energy, distance, sum_energy, sum_distance); distance = 0; } } printf("%d\n", get_result(solutions, sum_energy, sum_distance)); 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 | #include <set> #include <stdio.h> #define MAX_LENGTH 10000000 struct Solution { long long int energy; int length; bool operator<(const Solution &s) const { if (energy != s.energy) return energy < s.energy; else return length < s.length; } }; using Solutions = std::set<Solution>; void insert(Solutions &solutions, const Solution solution) { auto is_bad_element = [&solution](const Solution &s) { if (s.energy < solution.energy) return s.length >= solution.length; else if (s.energy == solution.energy) return s.length > solution.length; return false; }; auto it = solutions.lower_bound(solution); if (it != solutions.end()) { if (it->length > solution.length) { it = solutions.insert(it, solution); auto remove_from = it; while (remove_from != solutions.begin() && is_bad_element(*std::prev(remove_from))) remove_from--; if (it != remove_from) solutions.erase(remove_from, it); } } else { it = solutions.insert(it, solution); } } void add(Solutions &solutions, int energy, int distance, long long int &sum_energy, int &sum_distance) { auto it = solutions.lower_bound(Solution({-sum_energy, 0})); if (it != solutions.end()) insert(solutions, {-sum_energy, it->length - distance}); sum_energy += energy; sum_distance += distance; } int get_result(const Solutions &solutions, const long long int &sum_energy, const int &sum_distance) { int best_length = MAX_LENGTH; for (const auto &data : solutions) if (data.energy + sum_energy >= 0) best_length = std::min(best_length, data.length + sum_distance); if (best_length != MAX_LENGTH) return best_length; else return -1; } int main() { int n, energy, distance = 0, sum_distance = 0; long long int sum_energy = 0; Solutions solutions; scanf("%d", &n); for (int i = 1; i <= n; ++i) { scanf("%d", &energy); distance++; if (energy != 0) { if (solutions.empty()) { solutions.insert({0, 0}); sum_energy += energy; } else add(solutions, energy, distance, sum_energy, sum_distance); distance = 0; } } printf("%d\n", get_result(solutions, sum_energy, sum_distance)); return 0; } |