题目描述:
有N个鱼塘排成一排(N<100),每个鱼塘中有一定数量的鱼,例如:N=5时,如下表:
即:在第1个鱼塘中钓鱼第1分钟内可钓到10条鱼,第2分钟内只能钓到8条鱼,......,第5分钟以后再也钓不到鱼了。从第1个鱼塘到第2个鱼塘需要3分钟,从第2个鱼塘到第3个鱼塘需要5分钟,......
给出一个截止时间T(T<1000),设计一个钓鱼方案,从第1个鱼塘出发,希望能钓到最多的鱼。假设能钓到鱼的数量仅和已钓鱼的次数有关,且每次钓鱼的时间都是整数分钟。
输入格式:
共5行,分别表示:
第一行为整数N;
第二行为第1分钟各个鱼塘能钓到的鱼的数量,每个数据之间用一空格隔开;
第三行为每过1分钟各个鱼塘钓鱼数的减少量,每个数据之间用一空格隔开;
第四行为当前鱼塘到下一个相邻鱼塘需要的时间;
第五行为截止时间T。
输出格式:
仅一个整数,表示能钓到的最多的鱼。
输入样例:
5
10 14 20 16 9
2 4 6 5 3
3 5 4 4
14
输出样例
76
参考代码:
#include <bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
/*
只有在鱼塘钓鱼时,池塘的鱼才会减少。
从1顺序走到n池塘,因此枚举最远到达的i池塘 (1<= i <=n)池塘
不断减去路上花费的时间,用剩余的时间来找池塘中的鱼
采取枚举+贪心。
*/
int get[102],lost[102],go[102],times,n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>get[i];
}
for(int i=1;i<=n;i++)
{
cin>>lost[i];
}
for(int i=1;i<n;i++)
{
cin>>go[i];
}
cin>>times;
// 优先队列(大堆顶)优化,贪心从剩余鱼最多的池塘先开始钓.
priority_queue<pair<int,int> >q;
int walk=0,maxc=-1;
// 枚举最远走到的池塘编号
for(int i=1;i<=n;i++)
{
//剩余时间,减去到每个池塘间的时间
int st=times-walk;
// 赶不到这个池塘了,这之后也到不了,赶紧跑路溜了
if(st<=0)break;
int ans=0;
//存储到当前鱼塘能获取鱼的信息
for(int j=1;j<=i;j++)
{
q.push(make_pair(get[j],j));
}
// 剩余时间不为0,并且队列中的鱼塘中还有鱼时
while(st>0 && q.top().first>0)
{
pair<int,int> c=q.top();
q.pop();
// 当前鱼塘的鱼数
ans+=c.first;
// 当前鱼塘减少的鱼数
c.first-=lost[c.second];
// 更新当前鱼塘
q.push(c);
// 剩余时间减少
st--;
}
while(!q.empty())q.pop();
// 更新最多鱼数
maxc=max(ans,maxc);
// 累计走路需要的时间
walk+=go[i];
}
cout<<maxc<<endl;
}