Fresh Energy

           Nerver say die!

IT博客 首页 新随笔 联系 聚合 管理
  84 Posts :: 0 Stories :: 197 Comments :: 0 Trackbacks

设钓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;
}

posted on 2006-09-11 11:06 zhouditty 阅读(746) 评论(1)  编辑 收藏 引用 所属分类: ACM

Feedback

# re: pku1042 Gone Fishing 2008-04-23 16:09 火花的明天
学习 ,程序很清晰,读起来舒服  回复  更多评论
  

只有注册用户登录后才能发表评论。