题目描述
话说发源于小朋友精心设计的游戏被电脑组的童鞋们藐杀之后非常不爽,为了表示安慰和鼓励,VIP999 决定请他吃一次“年年大丰收”,为了表示诚意,他还决定亲自去钓鱼。
但是,因为还要准备 NOIP2013, z老师只给了他 HHH 个小时的空余时间,假设有 nnn 个鱼塘都在一条水平路边,从左边到右编号为 1, 2, 3 .. n 。
VIP是个很讲究效率的孩子,他希望用这些时间钓到尽量多的鱼。他从湖1出发,向右走,有选择的在一些湖边停留一定的时间钓鱼,最后在某一个湖边结束钓鱼。他测出从第 i 个湖到第 i+1 个湖需要走 5×Ti分钟路,还测出在第 i 个湖停留,第一个 5 分钟可以钓到 Fi 条鱼,以后每再钓 5 分钟,可以钓到的鱼量减少 Di ,若减少后的鱼量小于 0,则减少后的鱼量为 0 。为了简化问题,他假定没有其他人钓鱼,也不会有其他因素影响他钓到期望数量的鱼。请编程求出能钓最多鱼的数量。
输入输出格式
输入格式:
第一行:湖的数量n。
第二行:时间h(小时)。
第三行:n个数,f1f_1f1,f2f_2f2,… fnf_nfn。
第四行:n个数,d1d_1d1,d2d_2d2,….dnd_ndn。
第五行:n-1个数,t1t_1t1,t2t_2t2,….tn−1t_{n-1}tn−1
输出格式:
一个数,所能钓鱼的最大数量。
输入输出样例
输入样例#1:
2
1
10 1
2 5
2
输出样例#1:
31
说明
1 <= H <= 16
2 <= n <= 25
思路
首先感谢perisno大佬
枚举停止的池子,并计算出从头走到这里所需要的时间tm[i]
(输入时搞成前缀和)
则可钓鱼的时间为(h-tm[i])
将前i
个池子能钓的鱼push
进priority_queue
里,
在时间结束前pop
出当前能钓最多鱼的池子,
减去应减的数量再push
回去。
这样可以求出应在每个池子分别钓多久鱼。
答案为在每个池子停留的最优解的最大值。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int MAXN=1e5+5;
struct pond{
int sl,jian;
friend bool operator <(pond a,pond b){
return a.sl<b.sl;
}
} a[MAXN];
int tm[MAXN];
int n,h;
priority_queue<pond> q;
int main(){
cin>>n>>h;
h*=12;
for(int i=1;i<=n;++i){
cin>>a[i].sl;
}
for(int i=1;i<=n;++i){
cin>>a[i].jian;
}
for(int i=1;i<n;++i){
cin>>tm[i+1];
tm[i+1]+=tm[i];
}
int ans=0;
for(int i=1;i<=n&&h-tm[i]>0;++i){
int cnt=0;
int ti=h-tm[i];
for(int j=1;j<=i;++j){
q.push(a[j]);
}
while(!q.empty()&&ti){
pond u=q.top();
q.pop();
cnt+=u.sl;
u.sl-=u.jian;
if(u.sl>0)q.push(u);
--ti;
}
ans=max(ans,cnt);
}
cout<<ans<<endl;
return 0;
}