题目链接:https://cn.vjudge.net/problem/OpenJ_Bailian-1042
题意:John有h个小时的钓鱼时间,一共有n个湖泊,它们在一条直线上。从第1个湖开始,可以在任意一个湖停下,每到达一个湖,这个湖开始有f[i]条鱼,钓一次鱼需要5分钟,5分钟后这个湖的鱼的数量为上次数量减去d[i],并且从第i个湖到第i+1个湖需要ti*5的时间。如果某个时间段期望钓到的鱼数小于或者等于di,那么下一个时间段湖中将不再有鱼剩下。为了简化计划,John假设没有其他钓鱼人影响到他的钓鱼数目。目标是让他能钓到的鱼最多。在每个湖他所花的时间必须是5分钟的倍数。
分析:为了叙述方便,把钓5分钟鱼称为钓一次鱼。首先枚举John需要走过的湖泊数X,也就是假设他从湖泊1走到湖泊X,在湖泊X停止钓鱼,则路上花去的时间记为time[X]。在这个前提下,可以认为John能从一个湖“瞬间转移”到另一个湖,那么在任意一个时刻都可以从湖泊1到湖泊X中任选一个湖泊来钓鱼。因此,采取贪心策略,每次选一个鱼最多的湖泊来钓鱼。对于每个湖泊而言,由于在任何时候鱼的数量之和John在该湖钓鱼的次数有关,而和钓鱼的总次数无关,所以这个策略是最优的。假设一共允许钓k次鱼,那么每次在n个湖泊中选择鱼最多的一个湖泊钓,选择每次钓鱼地点的时间复杂度为O(n),总的时间复杂度为O(n^2)。如果用优先队列来做,总的时间复杂度可以降为O(nlogn)。
题意/分析-原作者:lyhvoyage
原文:https://blog.csdn.net/LYHVOYAGE/article/details/23289531
AC代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
const int maxn = 31;
struct Pond
{
int order,f,d;
friend bool operator < (const Pond &t1,const Pond &t2) {
if(t1.f == t2.f)
return t1.order > t2.order;
return t1.f < t2.f;
}
}Ponds[maxn];
int dis[maxn];
int times[maxn][maxn]; // times[i][j]记录最多走到i池塘时,第j个池塘的停留时间
int main()
{
int n,T;
while(scanf("%d",&n) && n) {
scanf("%d",&T);
T = T*12;
for(int i=1;i<=n;i++) {
scanf("%d",&Ponds[i].f);
Ponds[i].order = i;
}
for(int i=1;i<=n;i++)
scanf("%d",&Ponds[i].d);
for(int i=1;i<n;i++)
scanf("%d",&dis[i]);
memset(times,false,sizeof times);
int MaxFish = 0;
int MaxPond = 1;
// 最多走到第MaxPond个鱼塘 注意,初始化一定为1,因为若果所有鱼塘初始鱼量都为0,
// 那么后续对MaxPond的操作都不会进行,实际是John要一直在第一个鱼塘愣着啥也不干
int MaxFish_t;
int t;
for(int i=1;i<=n;i++) { // 当最多走到第i个鱼塘
t = T;
priority_queue<Pond> P;
for(int j=1;j<=i;j++)
P.push(Ponds[j]);
for(int j=1;j<i;j++)
t -= dis[j]; // 出去跑路还剩下的时间 单位:(5min)
MaxFish_t = 0;
Pond temp;
for(int j=1;j<=t;j++) {
temp = P.top();
MaxFish_t += temp.f;
temp.f = max(temp.f - temp.d,0);
times[i][temp.order]++;
P.pop();
P.push(temp);
}
if(MaxFish_t > MaxFish) {
MaxFish = MaxFish_t;
MaxPond = i;
}
}
for(int i=1;i<n;i++)
printf("%d, ",times[MaxPond][i]*5);
printf("%d\n",times[MaxPond][n]*5);
printf("Number of fish expected: %d\n\n", MaxFish);
}
}