poj 3111 best(二分)

来源:互联网 发布:女野人耶哥蕊特 知乎 编辑:程序博客网 时间:2024/06/05 02:04

Problem Link

best
最大化平均值。

分析

需要找的是
kj=1vijkj=1wij最大的编号,我们可以二分一下答案kj=1vijkj=1wijx,使得x最大变一下形式我们可以得到
kj=1vijkj=1wijx
vixwi0的最大的 x,这样对于每次答案就可以在O(nlgn)的时间内解决到了。

AC code

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<queue>#include <set>#define fi first#define se second#define INF 0x3f3f3f3fusing namespace std;typedef long long LL;typedef pair<LL,LL> PII;const int maxn = 1e5+10;int n,k;struct Jewel{  double v,w;  int id;};Jewel a[maxn];double x_cmp;bool cmp(const Jewel& x,const Jewel& y){  return x.v-x_cmp*x.w>y.v-y.w*x_cmp;}bool condition(double x){  x_cmp = x;  sort(a,a+n,cmp);  double sum = 0;  for(int i=0 ; i<k ; ++i)sum+=a[i].v-x_cmp*a[i].w;  return sum>=0;}void solve(){  double left =0,right = 1e7+10;  while (right>left+1e-5) {    double mid = (right+left)/2;    if(condition(mid)){      left = mid;    }else right = mid;  }  //std::cout << right <<endl;}int main(){    //freopen("in.txt","r",stdin);  while (cin>>n>>k) {    for(int i=0 ; i<n ; ++i)    {      scanf("%lf%lf",&a[i].v,&a[i].w );      a[i].id = i+1;    }    solve();    for(int i=0 ; i<k ; ++i)    printf("%d ",a[i].id);    std::cout << '\n';  }    return 0;}
0 0
原创粉丝点击