描述
http://poj.org/problem?id=3111
分析
二分.
最大化平均值(同POJ 2976 Dropping Tests).
不等式变形做就可以了.
注意:
1.算c的值的时候不用担心算爆,int会先被提升为double再做运算,所以r取INF也没关系,不会爆(最多是INF*INF).
2.但是r取INF精度就不够了,所以还是乖乖取max(a[i]/b[i])把...
3.排序的时候直接排成从大到小的,方便.
4.这题二分次数少了进度不够,次数多了超时.
1 #include<cstdio> 2 #include<algorithm> 3 using std :: sort; 4 using std :: max; 5 6 const int maxn=100005,INF=0x7fffffff; 7 int n,k; 8 int ans[maxn]; 9 struct point 10 { 11 int a,b,num; 12 double c; 13 }j[maxn]; 14 double x,y; 15 16 bool comp(point x,point y) { return x.c>y.c; } 17 18 bool C(double x) 19 { 20 for(int i=1;i<=n;i++) j[i].c=j[i].a-j[i].b*x; 21 sort(j+1,j+n+1,comp); 22 double sum=0; 23 for(int i=1;i<=k;i++) sum+=j[i].c; 24 return sum>=0; 25 } 26 27 void solve() 28 { 29 for(int i=0;i<25;i++) 30 { 31 double m=x+(y-x)/2; 32 if(C(m)) 33 { 34 x=m; 35 for(int i=1;i<=k;i++) ans[i]=j[i].num; 36 } 37 else y=m; 38 } 39 for(int i=1;i<k;i++) printf("%d ",ans[i]); 40 printf("%d",ans[k]); 41 } 42 43 void init() 44 { 45 scanf("%d%d",&n,&k); 46 for(int i=1;i<=n;i++) 47 { 48 scanf("%d%d",&j[i].a,&j[i].b); 49 j[i].num=i; 50 y=max(y,(double)j[i].a/(double)j[i].b); 51 } 52 } 53 54 int main() 55 { 56 freopen("k.in","r",stdin); 57 freopen("k.out","w",stdout); 58 init(); 59 solve(); 60 fclose(stdin); 61 fclose(stdout); 62 return 0; 63 }
时间: 2024-12-16 21:32:56