POJ1042 Gone Fishing

来源:互联网 发布:哪个软件可以唱小蛮腰 编辑:程序博客网 时间:2024/05/29 09:51

         本题的大意是:佳佳要钓鱼,有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;}

     程序没有优化过,不过希望起一个抛装引玉的作用。


原创粉丝点击