poj 3111 best(二分)
2017-01-09 20:10
309 查看
Problem Link
best最大化平均值。
分析
需要找的是∑kj=1vij∑kj=1wij最大的编号,我们可以二分一下答案∑kj=1vij∑kj=1wij≥x,使得x最大变一下形式我们可以得到
∑kj=1vij≥∑kj=1wij∗x即
∑vi−x∗wi≥0的最大的 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 0x3f3f3f3f using 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; }
相关文章推荐
- K Best POJ - 3111 (二分最大化平均值,注意用G++提交,不然TLE)
- poj3111- POJ - 3111 K Best (二分 + 01分数规划)
- K Best POJ - 3111 (二分最大化平均值,注意用G++提交,不然TLE)
- POJ 3111:K Best(思维+二分)
- poj 3111 K Best(二分)
- K Best POJ - 3111 (二分最大化平均值,注意用G++提交,不然TLE)
- POJ 3111 K Best + poj 2976 Dropping tests (二分, 最大化平均值)
- K Best POJ - 3111 (二分最大化平均值,注意用G++提交,不然TLE)
- poj 3111 K Best(二分-最大化平均值)
- K Best POJ - 3111 (二分最大化平均值,注意用G++提交,不然TLE)
- POJ 3111 K Best 二分(最小化平均值)
- POJ - 3111 K Best(二分)
- K Best POJ - 3111 (二分最大化平均值,注意用G++提交,不然TLE)
- K Best POJ - 3111 (二分最大化平均值,注意用G++提交,不然TLE)
- POJ 3111 K Best <最大化平均,二分>
- K Best POJ - 3111 (二分最大化平均值,注意用G++提交,不然TLE)
- POJ 3111 - K Best(二分搜索)
- K Best poj 3111 (01分数规划---二分搜索)
- poj 3111 K Best (二分搜索之最大化平均值之01分数规划)
- POJ - 3111 K Best (二分 + 01分数规划)