http://poj.org/problem?id=1042
题意:
John有h小时的时间去钓鱼,在一条直线上共有n个湖泊。一开始他位于第一个湖泊,每次钓鱼需要 一个时间单位(每个时间单位5分钟),可得到fi条鱼,且每过一个时间单位,下一个时间单位钓到的鱼减少di。从第i个湖泊到第i+1个湖泊需要ti个时间单位,且只能从标号低的湖泊向标号高的湖泊前进。john最多可以调到多少鱼?
输入多组数据,每组第一行数据为n(n=0时输入结束),共有n个湖泊,第二行为h,表示John有h个小时时间,第三行n个整数表示fi,第四行n个整数表示di,第五行为n-1个整数,表示ti。
每组数据输出两行,第一行表示在每个湖泊停留的时间(如果有剩余时间,则全都加在第一个湖泊上),用逗号分隔,第二行表示期望钓到鱼的数量。相邻的两组数据之间输出一个空行。
思路:
枚举一下最后一个湖泊,计算每次枚举的的湖泊的最大钓鱼的数量,取最大值即可。
每次找当前最大数量时,优先队列维护当前节点即可。
代码:
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string> #include<iomanip> #include<algorithm> #include<string.h> #include<queue> using namespace std; const int maxn=1100; typedef long long ll; class node { public: int name,num; node(int n=0,int u=0) { name=n; num=u; } bool operator < (const node &x) const{ if(num==x.num) return name>x.name; return num<x.num; } }; int n,h,f[40],d[50],t[50],ans[50]; int fishing(int p) { memset(ans,0,sizeof(ans)); int res=0; int time=h*12; for(int i=0; i<p; i++) time-=t[i]; priority_queue<node> q; for(int i=0; i<=p; i++) { if(f[i]>0) q.push(node(i,f[i])); } node x; while(time>0) { if(q.empty()) break; node cur=q.top(); q.pop(); time--; res+=cur.num; cur.num-=d[cur.name]; if(cur.num>0) q.push(cur); ans[cur.name]+=5; } return res; } int main() { int flag=0; while(cin>>n&&n) { if(flag) cout<<endl; flag=1; cin>>h; for(int i=0; i<n; i++) cin>>f[i]; for(int i=0; i<n; i++) cin>>d[i]; for(int i=0; i<n-1; i++) cin>>t[i]; int ma=0,manum=0,s; for(int i=0; i<n; i++) { int s=fishing(i); if(s>ma) { ma=s; manum=i; } } fishing(manum); int sum=0; for(int i=0; i<n; i++) sum+=ans[i]; for(int i=0; i<manum; i++) sum+=t[i]*5; sum=h*60-sum; cout<<ans[0]+sum; for(int i=1; i<n; i++) cout<<", "<<ans[i]; cout<<endl<<"Number of fish expected: "<<ma<<endl; } system("pause"); return 0; }