题目描述
话说发源于小朋友精心设计的游戏被电脑组的童鞋们藐杀之后非常不爽,为了表示安慰和鼓励,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
就是贪心呐,
首先依次枚举从1->i,找出可以钓到的最大值,
再从1->n全局找最大。
具体解析见代码
#include<cstdio>
#include<algorithm>
#define M 31
using namespace std;
int n,h,maxx=-1,ans=-1;
int f[M],d[M],t[M],w[M],tot[M];
int read() {
int x=0,f=1;char c=getchar();
while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') x=10*x+c-48,c=getchar();
return x*f;
}
int main() {
n=read();h=read();
for(int i=1;i<=n;i++) f[i]=read();
for(int i=1;i<=n;i++) d[i]=read();
for(int i=1;i<n;i++) t[i]=read();
for(int i=1;i<=n;i++) {//枚举走到第i个点,可以钓到最大的鱼数
int tim=h*60;
for(int j=1;j<i;j++)tim-=t[j]*5;//减去他走路的时间使他瞬移
for(int j=1;j<=i;j++) w[j]=f[j];
while(tim>0) {
int maxt=0,now;
for(int j=1;j<=i;j++) {//找最大的鱼塘,一直钓鱼
if(w[j]>maxt) //直到这个鱼塘不是最大,再找
maxt=w[j],now=j;//下一个最大鱼塘钓鱼
} //我没有用队列,多以钓一次鱼就
tot[i]+=w[now]; //重新再找一次最大鱼塘
w[now]=max(w[now]-d[now],0);//防止出现负数
tim-=5;
}
}
for(int i=1;i<=n;i++)
if(tot[i]>ans) ans=tot[i];
printf("%d\n",ans);
return 0;
}