题目来源:http://poj.org/problem?id=1042
题目大意:一个人在一个打算在编号1~n的湖里钓鱼,钓鱼是单向走的,不能往回走。给你n个湖,每个湖初始鱼的数量pi每次每个湖钓鱼后鱼的减少量di,第i个湖到第i+1湖的距离时间ti(单位是5min。。。),这个人可以在任何湖停止钓鱼求如何钓鱼才能才能在h小时内钓鱼量最多输出在每个湖钓鱼的时间。相同钓鱼量情况下,输出湖编号小的用时多的时间。
题目思路:用贪心+枚举即可。在枚举的大循环下,每一种枚举情况采用贪心计算出最优的钓鱼情况。
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int ans[30][30],f[30],d[30],t[30]; int main() { int h,n; cin>>n; while(true) { if(n==0) break; cin>>h; h*=12; memset(ans,0,sizeof(ans)); memset(f,0,sizeof(f)); memset(t,0,sizeof(t)); memset(d,0,sizeof(d)); 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]); } int ht,ft[30]; for(int ed=1;ed<=n;++ed)//枚举从第一个湖开始走 { memset(ft,0,sizeof(ft)); for(int i=1;i<=ed;++i) { ft[i]=f[i]; }//ft作为f的临时记录 ht=h;//记录剩余时间 for(int i=1;i<ed;++i) { ht-=t[i];//每一种枚举情况下除去走路花费的时间 } //剩余的时间来钓鱼 int k,emp=1;//emp代表当前的湖 while(ht>0&&emp<=ed)//时间用完或湖空为止 { k=1; for(int j=emp;j<=ed;++j) { if(ft[j]>ft[k]) { k=j; } }//找出最优的湖 //用ans[池塘编号][0]表示收获量,其余元素表示需要的时间 ans[ed][0]+=ft[k];//此次收获+ft[k] ++ans[ed][k];//记录在k湖花费了1单位时间 --ht;//时间消耗1单位 ft[k]-=d[k];//鱼的总量减少 ft[k]=ft[k]>0?ft[k]:0; for(int j=emp;j<=ed;++j) { if(ft[j]==0) ++emp;//若有湖空了,则进入下一个湖 else break; }//检查是否ed前的湖都已空 } if(ht>0) ans[ed][1]+=ht;//若尝试了所有的湖后时间有剩余 } int a=1; for(int i=2;i<=n;++i) { if(ans[i][0]>ans[a][0]) a=i; }//找出收益最大的方案 for(int i=1;i<=n;++i) { cout<<ans[a][i]*5;//输出所有的池塘所待的时间 if(i!=n) cout<<", "; } cout<<endl; cout<<"Number of fish expected: "<<ans[a][0]<<endl; cin>>n; if(n!=0) cout<<endl; } return 0; }
时间: 2024-10-05 21:47:00