大概思路:贪心+枚举
如果直接求解,最难算的就是从一个湖到另一个湖的过程,到底要不要走,要不要在这个湖钓鱼,这就比较难考虑。
那么我们可以换一种思维方式。因为人最终肯定是要停止在某一个湖的,那么我们就可以枚举最终停止的湖泊,这样从第一个湖到停止的湖的耗时就确定了。那么,我们就可以认为人可以在湖之间瞬间移动,为了能够钓到最多的鱼,就可以在每次选择湖泊时进行动态的排序,(可以用优先队列),选取鱼最大而且序号靠前的湖。
注意:当时间还没用完,却没有鱼时,我们就让人一直呆在1号湖耗完时间,即可。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
struct node
{
    int num,val;
    node(){}
    node (int x,int y)
    {
        num=x;
        val=y;
    }
    friend bool operator < (node a,node b)
    {
        if(a.val==b.val)
            return a.num>b.num;
        else
            return a.val<b.val;
    }
};
int n,h;
int f[30],d[30],t[30],minu[30],cnt[30];
priority_queue<node>que;
int solve(int p)
{
    while(!que.empty())
        que.pop();
    memset(cnt,0,sizeof(cnt));
    int all=0,ans=0;
    for(int i=1;i<=p;i++)
    {
        que.push(node{i,f[i]});
        if(i<p)
            all+=t[i];
    }
    all=h*12-all;//剩下的钓鱼时间
    while(all>0&&(!que.empty()))
    {
        node tp=que.top();
        que.pop();
        ans+=tp.val;
        tp.val-=d[tp.num];
        cnt[tp.num]++;
        if(tp.val<0)
            tp.val=0;
        que.push(tp);
        all--;
    }//如果直接把剩下的时间直接加在1号湖上,会wa,具体原因还不清楚
    return ans;
}
int main()
{
    while(scanf("%d",&n),n)
    {
        scanf("%d",&h);
        for(int i=1;i<=n;i++)
            scanf("%d",&f[i]);
        for(int i=1;i<=n;i++)
            scanf("%d",&d[i]);
        for(int i=1;i<n;i++)
            scanf("%d",&t[i]);
        memset(minu,0,sizeof(minu));
        int fish=-1;
        for(int i=1;i<=n;i++)//枚举结束的湖泊
        {
            int tmp=solve(i);
            if(fish<tmp)
            {
                fish=tmp;
                for(int j=1;j<=i;j++)
                    minu[j]=cnt[j];
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(i<n)
                printf("%d, ",minu[i]*5);
            else
                printf("%d\n",minu[i]*5);
        }
        printf("Number of fish expected: %d\n\n",fish);
    }
    return 0;
}