Gone Fishing

题意解释:
John现有h个小时的空闲时间,他打算去钓鱼。钓鱼的地方共有n个湖,所有的湖沿着一条单向路顺序排列(John每在一个湖钓完鱼后,他只能走到下一个湖继续钓),John必须从1号湖开始钓起,但是他可以在任何一个湖结束他此次钓鱼的行程。
此题以5分钟作为单位时间,John在每个湖中每5分钟钓的鱼数随时间的增长而线性递减。每个湖中头5分钟可以钓到的鱼数用fi表示,每个湖中相邻5分钟钓鱼数的减少量用di表示,John从任意一个湖走到它下一个湖的时间用ti表示。
求一种方案,使得John在有限的h小时中可以钓到尽可能多的鱼。

贪心+枚举
题解:
我们可以把总时间分为两个部分:在路上的时间和在钓鱼的时间。由于路是单行的,所以在路上的时间取决于走的最远距离,即到达的池塘的最大编号。 剩余的时间用于钓鱼。我们可以把移动+钓鱼的混合过程拆分为移动的过程和钓鱼的过程,即指定一个池塘为终点,移动过程即从起点到终点的过程,钓鱼的过程就是从起点到终点的各个池塘中选择池塘钓鱼,因为移动过程所需的时间已经在前面考虑过了,这个时候我们就可以认为需要移动的时候可以直接瞬间到达。然后,选择到哪些池塘钓鱼的策略采用贪心的方法,每个钓鱼的5分钟都选择期望最大的那一个池塘,每在选择一个池塘钓鱼5分钟,减少相应池塘的期望,增加计划中在该池塘钓鱼的时间,然后继续选择期望最大的池塘,直到钓鱼的时间不够,或者池塘里没有鱼了。如果池塘没有鱼了,还有时间的话,把多余的时间分配给第一个池塘。

#include<stdio.h>
#include<string.h>
int n,h,flag;
int fi[50],di[50],ti[50];
int nu[50];//拷贝的数目
int sum[50][50];//sum[i][j]:到i池塘为止钓的鱼的数目
//j 表示所花的时间
void slove()
{
    for(int i=1;i<=n;i++)
    {
        memset(nu,0,sizeof(nu));
        for(int j=1;j<=i;j++)//拷贝
            nu[j]=fi[j];
        int stay=1;//钓鱼的位置
        int maxn=1;//鱼数目的最大期望
        int hour=h;
        for(int j=1;j<i;j++)
            hour-=ti[j];
        while(hour>0&&stay<=i)
        {
            maxn=1;
            for(int j=stay;j<=i;j++)//寻找最大值
                if(nu[j]>nu[maxn])
                maxn=j;
            sum[i][0]+=nu[maxn];//更新已钓的鱼的个数
            hour--;//减少时间
            sum[i][maxn]++;//增加在这个池塘所待的时间
            nu[maxn]-=di[maxn];//减少池塘的鱼的个数
            if(nu[maxn]<0)
                nu[maxn]=0;
            for(int j=stay;j<=i;j++)//如过池塘没有鱼,前往下一个池塘
            {
                if(nu[j]==0)
                    stay++;
                else
                    break;
            }
        }
        //如果还有时间但是没有鱼了
        if(hour>0)
        sum[i][1]+=hour;
    }
    int staying=1;
    for(int i=2; i<=n; i++)//寻找最大值
    if(sum[i][0]>sum[staying][0])
        staying=i;
    for(int i=1; i<=n; i++)//输出每个湖所呆的时间
    {
        printf("%d",sum[staying][i]*5);
        if(i!=n)
        printf(", ");
    }
    printf("\nNumber of fish expected: %d\n",sum[staying][0]);

}

int main()
{

    while(scanf("%d",&n),n)
    {
        if(flag!=0)
            printf("\n");
        flag=1;
        memset(sum,0,sizeof(sum));
        scanf("%d",&h);
        for(int i=1;i<=n;i++)
            scanf("%d",&fi[i]);
        for(int i=1;i<=n;i++)
            scanf("%d",&di[i]);
        for(int i=1;i<n;i++)
            scanf("%d",&ti[i]);
        h=h*12;
        slove();
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43870114/article/details/89857845
今日推荐