博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
luogu P2107 小Z的AK计划
阅读量:7072 次
发布时间:2019-06-28

本文共 2581 字,大约阅读时间需要 8 分钟。

最近复习了一下堆,于是去luogu上找一些简单题写一写

 

贪心的想,小z不会到一半以后回头去Ak,因为这样从时间上想肯定是不优的,他可以早在之间经过时就AK

所以我们可以将所有机房按照横坐标排序
可以想到的是,我们最后肯定是要走过所有的机房,也就是说路程消耗的疲劳值是不可避免的。
我们只能尽可能的减少小ZAK所花费的时间
贪心的考虑,当我们在机房Ak所花费的时间长时,我们可能能在这个时间内AK更多的机房
所以当时间出问题时,我们肯定要取出堆顶删除以便AK更多的机房。
我们维护一个关于机房AK时间的大根堆,每次先假定要Ak,然后将时间丢入堆中,所到当前机房所花费的时间比总时间大,则移除堆顶
但是需要注意的是,移除堆顶时,我们的答案并不需要减少,因为刚刚插入一个,然后超过了总时间,在移除一个,刚刚好抵消
至于为什么只需要移除堆顶:
我在题解上看到过用while循环去移除堆顶的,然而实际并不需要,因为我们刚刚插入一个新元素
对于这个元素来说,若他不是堆中最大元素,显然我们移除最大的肯定就把这个新元素占的地方给腾出来了
若是最大元素,那么直接删除就等于过而不入,对答案没有影响

这样我们就能AC这道题

嗯好吧,其实思路是有些问题的

因为是这样的,可能的是,我们在当前这个机房,即使过而不入,单单是走过去,在加上之前的选择并AK机房耗费的时间就把总时间给超了

这样我们不得不多次弹出堆顶,同时在弹出第一个堆顶后,剩下的弹出多少个,答案数就要减去多少

好在这题没有卡

 

不会且没看stl的我选择手写二叉堆

1 #include
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 }

 

转载于:https://www.cnblogs.com/ywjblog/p/9858084.html

你可能感兴趣的文章
实现SPF垃圾邮件防护功能
查看>>
Slave IO: Yes Slave SQL: No Seconds Behind Mast...
查看>>
eclipse 使用Maven deploy命令部署构建到Nexus上
查看>>
大型系统中使用JMS优化技巧–Sun OpenMQ
查看>>
正则表达式-断言
查看>>
用git合并分支时,如何保持某些文件不被合并
查看>>
局部代码块、构造代码块、静态代码块
查看>>
聚类分析 ---- K-Means算法
查看>>
C語言最新標準-C11 「轉」
查看>>
SaltStack数据系统-Grains详解
查看>>
课程第三天内容《基础交换 三 》
查看>>
Spring(八):缓存
查看>>
全局函数指针作为模板参数
查看>>
URL access forbidden for unknown reason svn: acces
查看>>
kafka基本命令启动和测试
查看>>
你真的已经搞懂JavaScript了吗?
查看>>
个性化PS1变量
查看>>
IOS之UIWebView的使用
查看>>
分布式系统事务一致性解决方案
查看>>
ubuntu下nvm,node以及npm的安装与使用
查看>>