Problem Description
有N个鱼塘排成一排(N<100),每个鱼塘中有一定数量的鱼,例如:N=5时,如下表:
鱼塘编号 第1分钟能钓到的鱼的数量(1..1000) 每过1分钟钓鱼数的减少量(1..100) 当前鱼塘到下一个相邻鱼塘需要的时间( 单位:分钟)
1 10 2 3
2 14 4 5
3 20 6 4
4 16 5 4
5 9 3
即:在第1个鱼塘中钓鱼第1分钟内可钓到10条鱼,第2分钟内只能钓到8条鱼,……,第5分钟以后再也钓不到鱼了。从第1个鱼塘到第2个鱼塘需要3分钟,从第2个鱼塘到第3个鱼塘需要5分钟,……
给出一个截止时间T(T<1000),设计一个钓鱼方案,从第1个鱼塘出发,希望能钓到最多的鱼。假设能钓到鱼的数量仅和已钓鱼的次数有关,且每次钓鱼的时间都是整数分钟。
鱼塘编号 第1分钟能钓到的鱼的数量(1..1000) 每过1分钟钓鱼数的减少量(1..100) 当前鱼塘到下一个相邻鱼塘需要的时间( 单位:分钟)
1 10 2 3
2 14 4 5
3 20 6 4
4 16 5 4
5 9 3
即:在第1个鱼塘中钓鱼第1分钟内可钓到10条鱼,第2分钟内只能钓到8条鱼,……,第5分钟以后再也钓不到鱼了。从第1个鱼塘到第2个鱼塘需要3分钟,从第2个鱼塘到第3个鱼塘需要5分钟,……
给出一个截止时间T(T<1000),设计一个钓鱼方案,从第1个鱼塘出发,希望能钓到最多的鱼。假设能钓到鱼的数量仅和已钓鱼的次数有关,且每次钓鱼的时间都是整数分钟。
Input
输入有多组数据,每组数据共5行,分别表示:
第1行为N;
第2行为第1分钟各个鱼塘能钓到的鱼的数量,每个数据之间用一空格隔开;
第3行为每过1分钟各个鱼塘钓鱼数的减少量,每个数据之间用一空格隔开;
第4行为当前鱼塘到下一个相邻鱼塘需要的时间;
第5行为截止时间T;
第1行为N;
第2行为第1分钟各个鱼塘能钓到的鱼的数量,每个数据之间用一空格隔开;
第3行为每过1分钟各个鱼塘钓鱼数的减少量,每个数据之间用一空格隔开;
第4行为当前鱼塘到下一个相邻鱼塘需要的时间;
第5行为截止时间T;
Output
对于每组数据仅输出一个整数(不超过2^31-1),表示你的方案能钓到的最多的鱼。
Sample Input
5 10 14 20 16 9 2 4 6 5 3 3 5 4 4 14
Sample Output
76
// 关键字: 贪心+堆维护
/*
解题报告:从第一个池塘开始,一直往后走,如果能够在第i池塘继续钓鱼的值大于去下一个池塘钓鱼的值,
则继续在第i个池塘,不往前走。
*/
//标程:
#include<stdio.h> #include<string.h> struct ss { int num,cnt; }dp[110]; int num[110],t[110],sub[110]; int n,T,len; void Twh(int k) { ss a=dp[k]; int now=k,next=2*k; while(next<=len) { if(next<len && dp[next].num<dp[next+1].num) next++; if(a.num>=dp[next].num) break; dp[k]=dp[next]; k=next; next=next*2; } dp[k]=a; } int main() { //freopen("a.txt","r",stdin); while(scanf("%d",&n)!=EOF) { memset(dp,0,sizeof(dp)); int i,j; for(i=1;i<=n;i++) scanf("%d",num+i); for(i=1;i<=n;i++) scanf("%d",sub+i); for(i=1;i<n;i++) scanf("%d",t+i); scanf("%d",&T); int max=0,m=0; for(len=1;len<=n;len++) { for(i=1;i<=len;i++) { dp[i].num=num[i]; dp[i].cnt=i; } for(i=1;i<=len/2;i++) Twh(i); int sum=T-m, ans=0; while(sum>0 && dp[1].num>0) { ans+=dp[1].num; dp[1].num-=sub[dp[1].cnt]; Twh(1); sum--; } if(ans>max) max=ans; m+=t[len]; } printf("%d\n",max); } return 0; }