poj 2010 Moo University - Financial Aid(优先队列)
http://poj.org/problem?id=2010
题意就是,每只牛两个权(w,v),从m只牛中选w总和不超过W的n只牛,求这些牛按v排序后的中间那只牛v值最大为多少
超时
#include <cstdio> #include <cstring> #include <iostream> #include <cmath> #include <queue> #include <algorithm> using namespace std; typedef struct { int scr; int aid; } C; bool cmp(C c1,C c2) { if(c1.aid<c2.aid)return true; return false; } bool cmp2(C c1,C c2) { if(c1.scr<c2.scr)return true; return false; } bool operator <(const C&c1,const C&c2) { if(c1.scr<c2.scr)return true; return false; } int main() { int n,c,f; scanf("%d%d%d",&n,&c,&f); C cw[c]; priority_queue<C> pq; for(int i=0; i<c; i++) { scanf("%d%d",&cw[i].scr,&cw[i].aid); } sort(cw,cw+c,cmp); int s=0; for(int i=0; i<n; i++) { s+=cw[i].aid; } if(s>f) { printf("-1\n"); return 0; } sort(cw,cw+n,cmp2); for(int i=n; i<c; i++) { int cur=lower_bound(cw,cw+n,cw[i])-cw; if(cur>n/2) { int mx=0; //找前n/2的牛里面要钱最多的下标 for(int j=0; j<=n/2; j++) { if(cw[j].aid>cw[mx].aid) mx=j; } if(s-cw[mx].aid+cw[i].aid<=f)//如果把那个要钱最多的去掉加上这个没超钱,就换掉 { cw[mx]=cw[i]; } sort(cw,cw+n,cmp2);//重新按分数排序 } } printf("%d\n",cw[n/2].scr); }
过了。。主要就是有了明确的思路后再打码实现就可以了,经过这些天的思考,想通了,有了思路,不过后来没有立即实现,今天实现了一下,^ ^ 188MS
#include <cstdio> #include <cstring> #include <iostream> #include <cmath> #include <queue> #include <algorithm> using namespace std; typedef struct { int x; int y; } P; bool cmp(P p1,P p2) { if(p1.x<p2.x) return true; return false; } bool operator <(const P& p1,const P &p2) //<是大顶堆,开始写反了 { if(p1.y<p2.y) return true; return false; } int main() { int n,c,f,i; while(scanf("%d%d%d",&n,&c,&f)==3) { P p[c]; int mn[c],mx[c]; for(i=0; i<c; i++) { scanf("%d%d",&p[i].x,&p[i].y); } sort(p,p+c,cmp); priority_queue<P> pq; int s=0; for(i=0; i<n/2; i++) { pq.push(p[i]); s+=p[i].y; } for(i=n/2; i<=c-1-n/2; i++) { mn[i]=s; // printf("s1:%d ",s); pq.push(p[i]); s+=p[i].y; P t=pq.top(); s-=t.y; pq.pop(); } while(!pq.empty()) pq.pop(); s=0; for(i=c-1; i>c-1-n/2; i--) //>写成了< { pq.push(p[i]); s+=p[i].y; } for(i=c-1-n/2; i>=n/2; i--) { mx[i]=s; pq.push(p[i]); s+=p[i].y; P t=pq.top(); s-=t.y; pq.pop(); } /* for(i=n/2; i<=c-1-n/2; i++) { printf("%d,%d\n",mn[i]+mx[i]+p[i].y,p[i].x); } */ for(i=c-1-n/2; i>=n/2; i--) { s=0; s+=mn[i]+mx[i]+p[i].y; if(s<=f) //少了==的情况,忘记等于的条件也可以了 { printf("%d\n",p[i].x); break; } } if(i<n/2) printf("-1\n"); } }

浙公网安备 33010602011771号