本题的大意是:佳佳要钓鱼,有h个小时,n个湖,每个湖初始的状态是fi,每5分钟的钓鱼,fi要减少di的鱼数,并且从i-1个湖到i湖所需的时间为ti。佳佳如何安排才能钓到最多的鱼。
刚开始做这题时,并没有想到用贪心算法。而是通过对每一时刻t,选择是停留在该湖还是去下一个湖 ,这样可以用DP求得,d(i,n,k)表示在i时候,n湖,湖中鱼的数量为k时能取得的最大鱼数,但是这个状态有一个问题,那就是k是可以为负数的,为了记录此状态,k必须取很大,这样肯定是空间超了,而且此法虽然求最大值比较方便,但是,统计各个湖的信息比较麻烦。没办法了,只能用别的法子。网上有两个法子:DP和贪心。DP的话状态定义是d(i,j),表示在i湖停留j时间能取得的最大鱼数,由于这个我没用这个法子,就不多谈了。还有就是贪心算法,评论里面都说是黑书贪心算法的例题,里面主要说的是先统计从第1个湖到第i个湖的总时间,这样对于1到i湖之间的湖都可以认为瞬时就到了,这样的话,每次去最大的湖中钓鱼这样可以的到1到i个湖中能钓到的最大的鱼数。从1到n枚举i,就能得到最多的鱼数。
#include <stdio.h>
#include <string.h>
int n,totalTime;
int fi[26];
int di[26];
int ti[26];
int spendtime[26];
int temp[26];
int path[26]; //记录每个湖停留的时间
int fishes[26]; //用于存放每个湖的鱼数
int main()
{
int h;
int i,j;
int lt,sum,index,max,result,r_max;
freopen("test.txt","r",stdin);
while(1)
{
sum=0;
spendtime[0]=0;
r_max=0;
scanf("%d",&n);
if(n==0)
break;
scanf("%d",&h);
totalTime=12*h;
for(i=0;i<n;i++)
scanf("%d",&fi[i]);
for(i=0;i<n;i++)
scanf("%d",&di[i]);
for(i=0;i<n-1;i++)
{
scanf("%d",&ti[i]);
sum+=ti[i];
spendtime[i+1]=sum;
}
for(i=0;i<n;i++)
{
memcpy(fishes,fi,sizeof(fi));
memset(temp,0,sizeof(temp));
lt=totalTime-spendtime[i];
result=0;
while((lt--)>0)
{
max=0;
index=0;
for (j=0;j<=i;j++)
{
if(fishes[j]>max)
{
max=fishes[j];
index=j;
}
}
temp[index]++;
if(fishes[index]>=0)
{
result+=fishes[index];
fishes[index]-=di[index];
}
}
if(i==0 || r_max<result) //注意这里必须是小于,能保证尽量在序号小的湖停留
{
memcpy(path,temp,sizeof(temp));
r_max=result;
}
}
for(j=0;j<n-1;j++)
printf("%d, ",path[j]*5);
printf("%d\n",path[j]*5);
printf("Number of fish expected: %d\n",r_max);
printf("\n");
}
return 0;
}
程序没有优化过,不过希望起一个抛装引玉的作用。