题目描述
话说发源于小朋友精心设计的游戏被电脑组的童鞋们藐杀之后非常不爽,为了表示安慰和鼓励,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:
View Code
31
/* 据说这是贪心非常经典的题,然而蒟蒻不会 首先我们可以知道这个人不会走回头路,因为走回头路还不如钓完再往前走并且如果我们假设这个人可以瞬移的话,他每时刻都要选可以钓鱼的数量最大的湖,所以我们假设ans[i]为他只在前i个湖中钓鱼所得到的最大鱼的数量,先把路径减掉,每次找鱼数量最大的湖。 貌似可以优先队列优化,然而数据太弱没有必要 */ #include<cstdio> #include<iostream> #define M 30 using namespace std; int f[M],f2[M],d[M],t[M],ans[M],n,h; void init() { 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]); h*=60; } int main() { freopen("jh.in","r",stdin); init(); for(int i=1;i<=n;i++)//设在前i个鱼池中钓鱼 { int hp=h; for(int j=1;j<i;j++)//让人可以瞬移 hp-=t[j]*5; for(int j=1;j<=i;j++) f2[j]=f[j]; while(hp>0)//如果时间不够,结束 { int a=0; for(int j=1;j<=i;j++)//找鱼数量最大的湖 if(f2[j]>f2[a])a=j; ans[i]+=f2[a]; hp-=5; if(f2[a]>d[a])f2[a]-=d[a]; else f2[a]=0; if(!a)break;//如果湖里没有鱼了,结束 } } int tot=0; for(int i=1;i<=n;i++) tot=max(tot,ans[i]); printf("%d",tot); return 0; }