钓鱼
题目描述
话说发源于小朋友精心设计的游戏被电脑组的童鞋们藐杀之后非常不爽,为了表示安慰和鼓励,VIP999 决定请他吃一次“年年大丰收”,为了表示诚意,他还决定亲自去钓鱼。
但是,因为还要准备 NOIP2013, z老师只给了他 H H H 个小时的空余时间,假设有 n n n 个鱼塘都在一条水平路边,从左边到右编号为 1, 2, 3 … n 。
VIP是个很讲究效率的孩子,他希望用这些时间钓到尽量多的鱼。他从湖1出发,向右走,有选择的在一些湖边停留一定的时间钓鱼,最后在某一个湖边结束钓鱼。他测出从第 i i i 个湖到 i + 1 i+1 i+1个湖需要走 5 × t i 5 \times t_i 5×ti 分钟的路,还测出在第 i i i 个湖边停留,第一个5分钟可以钓到鱼 f i f_i fi,以后再每钓5分钟鱼,鱼量减少 d i d_i di。为了简化问题,他假定没有其他人钓鱼,也不会有其他因素影响他钓到期望数量的鱼。请编程求出能钓最多鱼的数量。
输入格式
第一行:湖的数量n。
第二行:时间h(小时)。
第三行:n个数, f 1 f_1 f1, f 2 f_2 f2,… f n f_n fn。
第四行:n个数, d 1 d_1 d1, d 2 d_2 d2,…. d n d_n dn。
第五行:n-1个数, t 1 t_1 t1, t 2 t_2 t2,…. t n − 1 t_{n-1} tn−1
输出格式
一个数,所能钓鱼的最大数量。
样例 #1
样例输入 #1
2
1
10 1
2 5
2
样例输出 #1
31
提示
1 <= H <= 16
2 <= n <= 25
代码
#include<bits/stdc++.h>
using namespace std;
struct P{
int fish,d,i;
}s[10000];
struct cmp{
bool operator () (P x,P y){
return x.fish<y.fish;
}
};
int t[1000];
int main(){
int n,h;
cin>>n>>h;h *= 12;
for (int i=1;i<=n;i++) cin>>s[i].fish;
for (int i=1;i<=n;i++){
cin>>s[i].d;s[i].i=i;
}
for (int i=2;i<=n;i++) cin>>t[i];
int ans=-1e8;
for (int i=1;i<=n;i++){
int cnt=0;
h-=t[i];
priority_queue<P,vector<P>,cmp > que;
for (int j=1;j<=i;j++) que.push(s[j]);
for (int j=1;j<=h;j++){
P no=que.top();
if (no.fish>0){
cnt+=no.fish;no.fish-=no.d;
que.pop();que.push(no);
}
}
ans=max(ans,cnt);
}
cout<<ans;
return 0;
}
分析
优先队列——priority_queue,priority_queue<
int
>是int 的优先队列,有关结构体的优先队列可以定义cmp
结构体struct cmp{ bool operator () (P x,P y){ return x.fish<y.fish; } }; priority_queue<P,vector<P>,cmp > que;
cmp
应重载()
运算符,这会更方便
如果可以消去移动时间,题目便可以变成每次取最多鱼的水池
的贪心题了
h-=t[i]
做到了此操作,结合优先队列,此题便AC了
ans=max(ans,cnt);
记得比较