链接:https://vjudge.net/problem/POJ-1042
思路:贪心题。首先中途花费的时间总和只跟最终的终点有关,所以考虑枚举终点。然后用一个优先队列储存当前能钓鱼的总量,每次取出最大的,然后减去减少量再放入队列,注意如果存在相等的钓鱼总量则取鱼塘序号(靠前面)较小的哪一个,然后一直直到时间<5就结束。
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 30;
//鱼塘,注意排序时如果相等就返回鱼塘序号较小的那一个
struct fish{
int f,d,t,p;
bool operator<(const fish &a1)const{
if(f==a1.f) return p>a1.p;
return f<a1.f;
}
}ff[maxn];
int cc[maxn],dd[maxn];
int n,h;
int main(){
int o = 0;
while(scanf("%d",&n)&&n){
memset(dd,0,sizeof(dd));
scanf("%d",&h);
for(int i=0;i<n;++i)scanf("%d",&ff[i].f);
for(int i=0;i<n;++i)scanf("%d",&ff[i].d);
for(int i=0;i<n-1;i++)scanf("%d",&ff[i].t);
for(int i=0;i<n;i++)ff[i].p = i;
int res = 0;
for(int i=0;i<n;i++){
int times = h*60;
memset(cc,0,sizeof(cc));
priority_queue<fish> q1;
int ans = 0;
for(int j=0;j<i;j++)
times-=ff[j].t*5;//枚举终点,除去中间花费的时间
for(int j=0;j<=i;++j)
q1.push(ff[j]);
while(times>=5&&!q1.empty()){
fish z = q1.top();
q1.pop();
times-=5;
cc[z.p]++;
ans+=z.f;
z.f= z.f - z.d; //扣去每次钓鱼后的鱼塘总量减少量,再入队
if(z.f<0)z.f=0;
q1.push(z);
}
if(ans>res){
res = ans;
for(int k=0;k<n;k++){
dd[k] = cc[k];
}
}
else if(ans==res){
int judge = 0;
for(int k=0;k<n;k++){
if(cc[k]>dd[k]){judge = 1;break;}
else if(cc[k]<dd[k])break;
else continue;
}
if(judge){
for(int k=0;k<n;k++){
dd[k] = cc[k];
}
}
}
}
if(o++)printf("\n");
for(int i=0;i<n-1;i++){
printf("%d, ",dd[i]*5);
}
printf("%d\n",dd[n-1]*5);
printf("Number of fish expected: %d\n",res);
}
return 0;
}