1. 程式人生 > >POJ 3111 K Best 二分 最大化平均值

POJ 3111 K Best 二分 最大化平均值

node double clas {} poj 答案 pac 無法 cst

1.題意:給一共N個物品,每個物品有重量W,價值V,要你選出K個出來,使得他們的平均單位重量的價值最高

2.分析:題意為最大化平均值問題,由於每個物品的重量不同所以無法直接按單位價值貪心,但是目標值有界且能判斷與最後答案的大小關系,所以用二分來做

3.代碼:

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <cmath>
 4 # include <algorithm>
 5 using namespace std;
 6 const double eps=1e-8;
 7
const int MAXN=100005; 8 int N,K; 9 int sgn(double x) 10 { 11 if(fabs(x)<eps) return 0; 12 if(x>0) return 1; 13 else return -1; 14 } 15 struct Node 16 { 17 int n; 18 double v,w; 19 Node(){} 20 Node(int nn,double vv,double ww) 21 { 22 23 n=nn; 24 v=vv;
25 w=ww; 26 } 27 }L[MAXN]; 28 struct OUT 29 { 30 int n; 31 double sum; 32 OUT(){} 33 OUT(int nn,double ss) 34 { 35 n=nn; 36 sum=ss; 37 } 38 }; 39 bool cmp(OUT x,OUT y) 40 { 41 return sgn(y.sum-x.sum)<0; 42 } 43 void Init() 44 { 45 double a,b;
46 for(int i=0;i<N;i++) 47 { 48 scanf("%lf%lf",&a,&b); 49 L[i]=Node(i+1,a,b); 50 } 51 } 52 void Solve() 53 { 54 OUT O[MAXN]; 55 double l=0.0; 56 double r=1e7; 57 while(sgn(r-l)!=0) 58 { 59 double mid=l+(r-l)/2.0; 60 for(int i=0;i<N;i++) 61 O[i]=OUT(L[i].n,L[i].v-L[i].w*mid); 62 sort(O,O+N,cmp); 63 double temp=0; 64 for(int i=0;i<K;i++) 65 temp+=O[i].sum; 66 if(sgn(temp)<0) r=mid; 67 else l=mid; 68 } 69 for(int i=0;i<K-1;i++) 70 printf("%d ",O[i].n); 71 printf("%d\n",O[K-1].n); 72 } 73 int main() 74 { 75 while(scanf("%d%d",&N,&K)!=EOF) 76 { 77 Init(); 78 Solve(); 79 } 80 return 0; 81 }

POJ 3111 K Best 二分 最大化平均值