51nod:1689 逛街
2016-08-08 22:08
148 查看
原题链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1689
一开始想枚举逛街的终点,然后开两个大根堆维护b值,分别保证喜爱店不少于k,以及在此前提下逛到的店尽可能多。具体实现是维持第一个堆元素数为k,每加入一个元素,如果c为1,就丢进第一个堆,并把堆顶丢到第二个,c为0直接丢进第二个。如果两个堆的元素b值之和超过T,就从第二个堆删元素。
但是这种写法最后的删元素部分有可能删去对答案有贡献的点,这时再把丢掉的元素维护起来,每次都差一下,然后就T了。
于是考虑每次删元素都看看第三个堆与第二个堆的优劣,删去无用元素,可以省去很多无用计算。
View Code
LYK喜欢逛街。
但是LYK时间有限,只有T个单位时间。
LYK从1号店出发,从1号店走到第i号店需要花费 ai 个单位的时间,这些店形成了一条直线,因此LYK从i号店到i+1号店花费的时间为 ai+1−ai 。若选择进去逛,则需要需要花费 bi 的时间。对于第i家店,LYK对其有个评估值 ci ,表示自己是否喜欢这家店。
LYK想在有限的时间内,逛无限的街,当然这是不可能的。
它有个目标,将走进去逛的店中 ci 的和加起来,要使得这个值 ≥ k,在此基础上,能逛的店越多越好。
它想知道最多能逛多少店。
若无法满足LYK的要求,输出-1。
Input
Output
Input示例
Output示例
一开始想枚举逛街的终点,然后开两个大根堆维护b值,分别保证喜爱店不少于k,以及在此前提下逛到的店尽可能多。具体实现是维持第一个堆元素数为k,每加入一个元素,如果c为1,就丢进第一个堆,并把堆顶丢到第二个,c为0直接丢进第二个。如果两个堆的元素b值之和超过T,就从第二个堆删元素。
但是这种写法最后的删元素部分有可能删去对答案有贡献的点,这时再把丢掉的元素维护起来,每次都差一下,然后就T了。
于是考虑每次删元素都看看第三个堆与第二个堆的优劣,删去无用元素,可以省去很多无用计算。
#include<queue> #include<cstdio> #include<algorithm> #define MN 100001 using namespace std; int read_p,read_ca; inline int read(){ read_p=0;read_ca=getchar(); while(read_ca<'0'||read_ca>'9') read_ca=getchar(); while(read_ca>='0'&&read_ca<='9') read_p=read_p*10+read_ca-48,read_ca=getchar(); return read_p; } int n,m,k,a[MN],b[MN],mmh=-1,A; long long T=0; priority_queue <int> q,Q,S; int main(){ register int i; n=read();m=read();k=read(); for (i=1;i<=n;i++) a[i]=read(); for (i=1;i<=n;i++) b[i]=read(); for (i=1;i<=n;i++){ if (read()) if (int(q.size())<k) q.push(b[i]);else q.push(b[i]),Q.push(q.top()),q.pop();else Q.push(b[i]); T+=b[i]; if (int(q.size())<k) continue; while (T+a[i]>m&&(!Q.empty())) T-=Q.top(),S.push(-Q.top()),Q.pop(); while (!S.empty()&&T+a[i]-S.top()<=m) T-=S.top(),Q.push(-S.top()),S.pop(); while (!S.empty()&&-S.top()<Q.top()){ T-=S.top();Q.push(-S.top());S.pop(); while (T+a[i]>m&&(!Q.empty())) T-=Q.top(),S.push(-Q.top()),Q.pop(); } if (T+a[i]<=m&&k+int(Q.size())>mmh) mmh=k+int(Q.size()); } printf("%d\n",mmh); }
View Code
LYK喜欢逛街。
但是LYK时间有限,只有T个单位时间。
LYK从1号店出发,从1号店走到第i号店需要花费 ai 个单位的时间,这些店形成了一条直线,因此LYK从i号店到i+1号店花费的时间为 ai+1−ai 。若选择进去逛,则需要需要花费 bi 的时间。对于第i家店,LYK对其有个评估值 ci ,表示自己是否喜欢这家店。
LYK想在有限的时间内,逛无限的街,当然这是不可能的。
它有个目标,将走进去逛的店中 ci 的和加起来,要使得这个值 ≥ k,在此基础上,能逛的店越多越好。
它想知道最多能逛多少店。
若无法满足LYK的要求,输出-1。
Input
第一行三个整数n(1<=n<=100000),T(1<=T<=10^9),k(0<=k<=n)。 接下来一行n个数,表示ai(a1=0,a1<a2<...<an<=10^9)。 接下来一行n个数,表示bi(1<=bi<=10^9)。 接下来一行n个数,表示ci(0<=ci<=1)。
Output
一行表示答案。
Input示例
4 11 1 0 1 2 10 1 1 1 1 0 0 0 1
Output示例
1
相关文章推荐
- 保持时间与建立时间
- SCEA的基本知识
- 操作系统之分页分段介绍
- hdu5808 整体二分
- 互联网时代的密码记忆模型
- No module named ERROR: conda update scikit-learn (also scipy and numpy)
- 2016/07 Week1
- equal 源码剖析
- [nRF51822] 7、基础实验代码解析大全(前十)
- PHPExcel中文开发手册翻译版(2)
- Android开发环境搭建详细图解
- iis中同时使用isapi_rewrite3和url重写模块的注意点
- 《Windows程序设计》读书笔十二 剪贴板
- AT89C5131实现U盘
- Day08、扫雷游戏练习、函数(调用、实参、形参)
- zookeeper leader选举源码实现
- 公司换了个办公场所,产生一些小感悟
- 日常小结-关于模拟登陆的小结-okhttp库的使用小结
- 王爽《汇编语言》实验10.3——数值显示
- URI和URL的区别,请举例说明。