luogu P2107 小Z的AK計劃

最近複習了一下堆,因而去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 } 
相關文章
相關標籤/搜索