最近複習了一下堆,因而去luogu上找一些簡單題寫一寫c++
貪心的想,小z不會到一半之後回頭去Ak,由於這樣從時間上想確定是不優的,他能夠早在之間通過時就AK
因此咱們能夠將全部機房按照橫座標排序
能夠想到的是,咱們最後確定是要走過全部的機房,也就是說路程消耗的疲勞值是不可避免的。
咱們只能儘量的減小小ZAK所花費的時間
貪心的考慮,當咱們在機房Ak所花費的時間長時,咱們可能能在這個時間內AK更多的機房
因此當時間出問題時,咱們確定要取出堆頂刪除以便AK更多的機房。
咱們維護一個關於機房AK時間的大根堆,每次先假定要Ak,而後將時間丟入堆中,所到當前機房所花費的時間比總時間大,則移除堆頂
可是須要注意的是,移除堆頂時,咱們的答案並不須要減小,由於剛剛插入一個,而後超過了總時間,在移除一個,剛恰好抵消
至於爲何只須要移除堆頂:
我在題解上看到過用while循環去移除堆頂的,然而實際並不須要,由於咱們剛剛插入一個新元素
對於這個元素來講,若他不是堆中最大元素,顯然咱們移除最大的確定就把這個新元素佔的地方給騰出來了
如果最大元素,那麼直接刪除就等於過而不入,對答案沒有影響git
這樣咱們就能AC這道題ui
嗯好吧,其實思路是有些問題的spa
由於是這樣的,可能的是,咱們在當前這個機房,即便過而不入,單單是走過去,在加上以前的選擇並AK機房耗費的時間就把總時間給超了code
這樣咱們不得很少次彈出堆頂,同時在彈出第一個堆頂後,剩下的彈出多少個,答案數就要減去多少blog
好在這題沒有卡排序
不會且沒看stl的我選擇手寫二叉堆get
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define uint unsigned int 4 #define ull unsigned long long 5 using namespace std; 6 const int maxn = 110000; 7 struct shiki { 8 ll x, t; 9 }a[maxn]; 10 ll heap[maxn << 1], tot = 0, num = 0; 11 ll n, m, top = 0; 12 ll ans = 0; 13 14 inline ll read() { 15 ll x = 0, y = 1; 16 char ch = getchar(); 17 while(!isdigit(ch)) { 18 if(ch == '-') y = -1; 19 ch = getchar(); 20 } 21 while(isdigit(ch)) { 22 x = (x << 1) + (x << 3) + ch - '0'; 23 ch = getchar(); 24 } 25 return x * y; 26 } 27 28 inline void up(int p) { 29 while(p > 1) { 30 if(heap[p] > heap[p / 2]) { 31 swap(heap[p], heap[p / 2]); 32 p /= 2; 33 } 34 else break; 35 } 36 } 37 38 inline void down(int p) { 39 int s = p * 2; 40 while(s <= tot) { 41 if(s < tot && heap[s] < heap[s + 1]) s++; 42 if(heap[p] < heap[s]) { 43 swap(heap[s], heap[p]); 44 p = s, s = p >> 1; 45 } 46 else break; 47 } 48 } 49 50 inline void extract() { 51 heap[1] = heap[tot--]; 52 down(1); 53 } 54 55 inline void insert(ll k) { 56 heap[++tot] = k; 57 up(tot); 58 } 59 60 inline bool cmp(shiki a, shiki b) { 61 return a.x < b.x;} 62 63 inline int get_top(){return heap[1];} 64 65 int main() { 66 n = read(), m = read(); 67 for(int i = 1; i <= n; ++i) { 68 ll x = read(), t = read(); 69 if(x <= m && t <= m) { 70 a[++top].x = x; 71 a[top].t = t; 72 } 73 } 74 sort(a + 1, a + top + 1, cmp); 75 for(int i = 1; i <= top; ++i) { 76 insert(a[i].t); 77 num += (a[i].x - a[i - 1].x) + a[i].t; 78 if(num <= m) ans++; 79 if(num > m) { 80 num -= get_top(); 81 extract(); 82 } 83 } 84 printf("%lld\n", ans); 85 return 0; 86 }