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