题目描述
话说发源于小朋友精心设计的游戏被电脑组的童鞋们藐杀之后非常不爽,为了表示安慰和鼓励,VIP999决定请他吃一次“年年大丰收”,为了表示诚意,他还决定亲自去钓鱼,但是,因为还要准备2013NOIP,z老师只给了他H(1<=H<=16)个小时的空余时间,假设有N(2<=n<=25)个鱼塘都在一条水平路边,从左边到右编号为1、2、3、。。。、n)。VIP是个很讲究效率的孩子,他希望用这些时间钓到尽量多的鱼。他从湖1出发,向右走,有选择的在一些湖边停留一定的时间钓鱼,最后在某一个湖边结束钓鱼。他测出从第I个湖到I+1个湖需要走5*ti分钟的路,还测出在第I个湖边停留,第一个5分钟可以钓到鱼fi,以后再每钓5分钟鱼,鱼量减少di。为了简化问题,他假定没有其他人钓鱼,也不会有其他因素影响他钓到期望数量的鱼。请编程求出能钓最多鱼的数量。
输入输出格式
输入格式:
第一行:湖的数量n。
第二行:时间h(小时)。
第三行:n个数,f1,f2,…fn。
第四行:n个数,d1,d2,….dn。
第五行:n-1个数,t1,t2,….tn-1
输出格式:
一个数,所能钓鱼的最大数量。
输入输出样例
输入样例#1:
2 1 10 1 2 5 2
输出样例#1:
31
题解:
贪心,考虑枚举我们现在一定会走到那个湖,然后先将时间先扣上,然后我们每次选取
扣除时间后可到达的湖中,打怪经验最多的关卡,用优先队列,维护一下就可以了,正确性十分显
然,交给读者思考。
代码:
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <cmath> #include <iostream> #include <queue> using namespace std; struct node{ int zhi,id; bool operator < (const node &x)const{ return x.zhi>zhi; } }; int n,h; int f[100],d[100],t[100],ans=0; priority_queue<node> q; void work(int hh){ while(!q.empty()) q.pop(); int tot=0,tim=h*12; for(int i=1;i<hh;i++) tim-=t[i]; if(tim<=0) return; for(int i=1;i<=hh;i++) q.push((node){f[i],i}); while(tim>0&&!q.empty()){ node x=q.top();q.pop(); tot+=x.zhi; tim--; if(x.zhi-d[x.id]>0) q.push((node){x.zhi-d[x.id],x.id}); } ans=max(ans,tot); } int main() { scanf("%d%d",&n,&h); for(int i=1;i<=n;i++) scanf("%d",&f[i]); for(int i=1;i<=n;i++) scanf("%d",&d[i]); for(int i=1;i<=n;i++) scanf("%d",&t[i]); for(int i=1;i<=n;i++) work(i); printf("%d",ans); return 0; }