大概题意:约翰有h个小时可用来钓鱼,该区域有n个湖泊,第i个湖在最初的5分钟内捕获的鱼的数量是fi
鱼每过5分钟减少di条,如果预计在一段时间内捕获的鱼的数量小于或等于di,则在下一个时间段内湖中将不再有鱼。
湖泊沿着一条单向道路可达,对于每个湖,从湖i到湖i+1所需要的5分钟间隔为ti个(他可以在任意湖边停下)
求约翰最大能钓到的鱼的条数.
鱼每过5分钟减少di条,如果预计在一段时间内捕获的鱼的数量小于或等于di,则在下一个时间段内湖中将不再有鱼。
湖泊沿着一条单向道路可达,对于每个湖,从湖i到湖i+1所需要的5分钟间隔为ti个(他可以在任意湖边停下)
求约翰最大能钓到的鱼的条数.
解题思路:(枚举+贪心)
1.枚举约翰从第一个湖开始可以走到的终点
2.将时间分成走路花的时间和钓鱼花的时间,每次计算时将走路花的时间扣除,即可视作瞬间到达
3.每5分钟将所有湖以期望从大到小排序,每次挑选鱼最多的湖(贪心),进行计算,直至湖里没有鱼或者没有时间
注意事项:
1.因为路为单向可达,故在选取期望最大的湖时,若有两湖或多湖期望相同,序号小的应优先考虑
2.在对期望进行减法计算时,若期望相减之后为负数,应将其置为0
3.若所有湖都没有鱼,且还有剩余时间,默认将剩余时间加到第一个湖上
4.注意输出格式(粗心,报了很多次PE)
2.在对期望进行减法计算时,若期望相减之后为负数,应将其置为0
3.若所有湖都没有鱼,且还有剩余时间,默认将剩余时间加到第一个湖上
4.注意输出格式(粗心,报了很多次PE)
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
int f,d,p;
};
node lake[30];
int fi[30];
int time[30];
int sum[30];
int stay[30][30];
bool cmp(node a,node b)
{
if(a.f==b.f)
return a.p<b.p;
return a.f>b.f;
}
int main()
{
int n,h,h1;
while(~scanf("%d",&n)&&n)
{
memset(time,0,sizeof(time));
memset(sum,0,sizeof(sum));
memset(stay,0,sizeof(stay));
scanf("%d",&h);
for(int i=0;i<n;i++)
{
scanf("%d",&lake[i].f);
fi[i]=lake[i].f;
lake[i].p=i;
}
for(int i=0;i<n;i++)
scanf("%d",&lake[i].d);
for(int i=1;i<n;i++)
scanf("%d",&time[i]);
int maxx=-1,sign=-1;
//枚举终点
for(int i=0;i<n;i++)
{
h1=h*60;//换算进制
for(int j=0;j<=i;j++)//走路的时间
h1-=time[j]*5;
if(h1<=0)
break;
while(h1)
{
if(i!=0)
{
sort(lake,lake+i+1,cmp);//第一个湖为最多鱼的湖
}
if(lake[0].f==0)
break;
else
{
sum[i]+=lake[0].f;//总和
stay[lake[0].p][i]+=5;//呆的时间
if(lake[0].f>lake[0].d)
lake[0].f-=lake[0].d;
else
lake[0].f=0;
h1-=5;
}
}
if(h1>0)
stay[0][i]+=h1;
if(sum[i]>maxx)
{
maxx=sum[i];
sign=i;
}
for(int j=0;j<=i;j++)//重置
lake[j].f=fi[lake[j].p];
}
for(int i=0;i<n;i++)
{
printf("%d",stay[i][sign]);
if(i!=n-1)
printf(", ");
}
printf("\n");
printf("Number of fish expected: %d\n",maxx);
printf("\n");
}
return 0;
}