设钓5分钟鱼称为钓一次鱼。枚举需要走过的湖泊数X(从1到X),则路上花去时间T= Ti(1~X-1)。支付时间后,就可以认为能从一个湖‘瞬移’到另一个湖,即在任意时刻可以从湖1到X中任选一个钓一次鱼。
(由于任何时候鱼的数目只和在该湖钓鱼的次数有关,和总次数无关)所以用贪心策略每次选一个鱼最多的湖泊钓一次鱼就能得到最优值。 (贪心+模拟)
#include <iostream>
#include <algorithm>
using namespace std;
int f[26]={0}; //fish expected in the first 5 minutes
int d[26]={0}; //decrease rate
int t[26]={0}; //time from lake i to i+1
struct P{
int f,i;
bool operator<(const P& b)const{ //运算符<重载 鱼数多的排在前,然后到池塘编号小的排前
if(f!=b.f) return f<b.f;
return i>b.i;
}
};
P p[30];
int main()
{
int n,maxfish,sum;
int s[26]; //time to stay at lake i
int stay[26];
int h,time;
bool first=1;
cin>>n;
while(n!=0)
{
cin>>h;
maxfish=-1;
time=h*12; //how many 5 minutes
for(int i=1;i<=n;i++)
cin>>f[i];
for(i=1;i<=n;i++)
cin>>d[i];
for(i=1;i<=n-1;i++)
cin>>t[i];
for(i=1;i<=n;i++){ //枚举n个湖
sum=0;
memset(s,0,sizeof(s));
for(int j=1;j<=i;j++)
{
p[j-1].f=f[j]; p[j-1].i=j;
}
make_heap(p,p+i); //构造大顶堆,堆顶在p[i-1]
for(int tm=1;tm<=time; tm++)
{ //可以钓time次鱼
pop_heap(p,p+i); //p[i-1]出堆,调整其它元素
int pf=p[i-1].f;
int pi=p[i-1].i;
sum+=pf;
s[pi]++; //在pi湖钓一次鱼
p[i-1].f=(pf-d[pi]>0)?(pf-d[pi]):0;
push_heap(p,p+i); //将p[i-1]加入堆,重新调整堆
}
if(sum>maxfish)
{
maxfish=sum;
memcpy(stay,s,sizeof(s));
}
time-=t[i];
}
if (first==1) first=0;
else cout<<endl;
for(i=1;i<=n-1;i++)
cout<<stay[i]*5<<", ";
cout<<stay[n]*5<<endl;
cout<<"Number of fish expected: "<<maxfish<<endl;
cin>>n;
}
return 0;
}