POJ 1042 枚举+优先队列
来源:互联网 发布:linux怎么运行脚本 编辑:程序博客网 时间:2024/05/21 17:08
//11074526c00h00g1042Accepted572K125MSG++3624B2012-12-03 19:05:06//思想:枚举,使用优先队列实现的,见黑书 //tm数组竟然不能开//runtime error,开始理解错了,以为是将时间加到第一个捕到鱼的湖上面,其实是加在第一个湖上面就行了 #include<stdio.h>#include<stdlib.h>#include<queue>#include<string.h>using namespace std;int n,h;struct Node{ int id;//用来标识lake的id int fi;//剩余鱼的数量 int di;//每五分钟减少的数量 int time;//在该湖中钓鱼的次数 bool operator<(const Node &nd) const{ //若fi相同的话,需要按照id小的顺序选择 if(fi!=nd.fi) return fi<nd.fi; else return id>nd.id; } Node(){ time=0; }};Node lake[30];int ans[30];int tmm[30];//t1表示从湖1到湖2的行驶时间需要乘以5 priority_queue<Node> q;void clear(){ while(!q.empty()) q.pop();}//表示每一个湖使用的时间,初始化为0 int main(){ while(scanf("%d",&n)!=EOF&&n){ scanf("%d",&h); h=h*60; for(int i=1;i<=n;i++){ scanf("%d",&lake[i].fi); lake[i].id=i; } for(int i=1;i<=n;i++) scanf("%d",&lake[i].di); //tmm表示从湖i到湖i+1所需要的时间 for(int i=1;i<n;i++) scanf("%d",&tmm[i]); //因为一开始在湖1的位置所以tmm[0]表示从湖0到湖1的时间 //枚举每一个湖 tmm[0]=0; int tmm_left,max=-1; for(int i=1;i<=n;i++){ tmm_left=0; for(int j=0;j<i;j++) tmm_left+=tmm[j]*5; //剩余可使用时间 tmm_left=h-tmm_left; //湖更多的话,时间更不够了,所以跳出 if(tmm_left<=0) break; else{ clear(); for(int j=1;j<=i;j++) q.push(lake[j]); //剩余钓鱼次数 int t=tmm_left/5,sum=0; Node tmmp; while(t>0){ tmmp=q.top(); //时间没用完,鱼钓完了 if(tmmp.fi<=0) break; q.pop(); t--; sum+=tmmp.fi; tmmp.fi-=tmmp.di; tmmp.time++; q.push(tmmp); } //时间没有用完,鱼就钓完了 if(t>0){ //ll表示剩下的时间,需要添加到第一个访问的湖的身上 int ll=t*5; if(max<sum){ max=sum; memset(ans,0,sizeof(ans)); Node tmmp; while(!q.empty()){ tmmp=q.top(); q.pop(); //该湖使用过 if(tmmp.time>0){ ans[tmmp.id]=tmmp.time*5; } } ans[1]+=ll; } } //时间用完了 else{ if(max<sum){ max=sum; memset(ans,0,sizeof(ans)); Node tmmp; while(!q.empty()){ tmmp=q.top(); q.pop(); //该湖使用过 if(tmmp.time>0){ ans[tmmp.id]=tmmp.time*5; } } } } }//end else }//end for for(int i=1;i<=n;i++){ if(i!=n) printf("%d, ",ans[i]); else printf("%d",ans[i]); } printf("\n"); printf("Number of fish expected: %d\n",max); printf("\n"); } return 0;}