#include <iostream> #include <cstdint> #include <vector> #include <utility> #include <algorithm> #include <bitset> #include <limits> #include <set> using namespace std; struct point{ int64_t cumsum; int score; point(int64_t cumsum_, int score_):cumsum(cumsum_), score(score_) {} bool operator < (const point &rhs) const { return (cumsum>rhs.cumsum || ( cumsum==rhs.cumsum && score<rhs.score) ) ; } }; int main() { std::ios::sync_with_stdio(false); cin.tie(0); int n; cin>>n; vector <int > tab; tab.reserve(n); vector <int64_t> cumsum; cumsum.reserve(n+0); cumsum.push_back(0); int m=n; int64_t accu =0; while (m-->0){ int t; cin>>t; tab.push_back(t); accu+=t; cumsum.push_back(accu); } if (cumsum.back()<0){ cout<<"-1"<<endl; return 0; } vector <int> subsol; subsol.reserve(n+1); //------------------- /* set<point> optimal; optimal.insert(point{0,0}); optimal.insert(point{2,0}); optimal.insert(point{4,1}); optimal.insert(point{4,2}); optimal.insert(point{4,0}); optimal.insert(point{5,3}); for (auto it = begin(optimal); it!= end(optimal); it++){ cout<<it->cumsum<<" "<<it->score<<endl; } subsol.push_back(0); for (int i=0; i<n; i++){ int best = 1000000000; //kończy się na pozycji i-tej. if (cumsum[i+1]>=0) optimal.lower_bound(point(cumsum[i+1]+1,0)); for (int j=i; j>=0; j--){ if (cumsum[i+1]-cumsum[j]>=0){ best = min (best, i-j + subsol[j]); } } subsol.push_back(best); } cout<< subsol.back()<<endl; */ // O(n^2) subsol.push_back(0); for (int i=0; i<n; i++){ int best = 1000000000; //kończy się na pozycji i-tej. for (int j=i; j>=0; j--){ if (cumsum[i+1]-cumsum[j]>=0){ best = min (best, i-j + subsol[j]); } } subsol.push_back(best); } cout<< subsol.back()<<endl; 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 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | #include <iostream> #include <cstdint> #include <vector> #include <utility> #include <algorithm> #include <bitset> #include <limits> #include <set> using namespace std; struct point{ int64_t cumsum; int score; point(int64_t cumsum_, int score_):cumsum(cumsum_), score(score_) {} bool operator < (const point &rhs) const { return (cumsum>rhs.cumsum || ( cumsum==rhs.cumsum && score<rhs.score) ) ; } }; int main() { std::ios::sync_with_stdio(false); cin.tie(0); int n; cin>>n; vector <int > tab; tab.reserve(n); vector <int64_t> cumsum; cumsum.reserve(n+0); cumsum.push_back(0); int m=n; int64_t accu =0; while (m-->0){ int t; cin>>t; tab.push_back(t); accu+=t; cumsum.push_back(accu); } if (cumsum.back()<0){ cout<<"-1"<<endl; return 0; } vector <int> subsol; subsol.reserve(n+1); //------------------- /* set<point> optimal; optimal.insert(point{0,0}); optimal.insert(point{2,0}); optimal.insert(point{4,1}); optimal.insert(point{4,2}); optimal.insert(point{4,0}); optimal.insert(point{5,3}); for (auto it = begin(optimal); it!= end(optimal); it++){ cout<<it->cumsum<<" "<<it->score<<endl; } subsol.push_back(0); for (int i=0; i<n; i++){ int best = 1000000000; //kończy się na pozycji i-tej. if (cumsum[i+1]>=0) optimal.lower_bound(point(cumsum[i+1]+1,0)); for (int j=i; j>=0; j--){ if (cumsum[i+1]-cumsum[j]>=0){ best = min (best, i-j + subsol[j]); } } subsol.push_back(best); } cout<< subsol.back()<<endl; */ // O(n^2) subsol.push_back(0); for (int i=0; i<n; i++){ int best = 1000000000; //kończy się na pozycji i-tej. for (int j=i; j>=0; j--){ if (cumsum[i+1]-cumsum[j]>=0){ best = min (best, i-j + subsol[j]); } } subsol.push_back(best); } cout<< subsol.back()<<endl; return 0; } |