Prepare

# poj 2976 Dropping tests（01分数规划+二分）

【题目大意】：给n个二元组，叫你从中去掉k个，使得sigema(100*a[i]-b[i])最大

【解题思路】：我们不妨令ans=sigema(100*a[i]-b[i])...得到sigema(a[i])*100-sigema(b[i])*ans=0;

然后...接下就是二分...求max就可以了...

【代码】：

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <string>
#include <cctype>
#include <map>
#include <iomanip>

using namespace std;

#define eps 1e-8
#define pi acos(-1.0)
#define inf 1<<30
#define linf 1LL<<60
#define pb push_back
#define lc(x) (x << 1)
#define rc(x) (x << 1 | 1)
#define lowbit(x) (x & (-x))
#define ll long long

double a[1100],b[1100],tmp[1100];
int n,k;
double summ;

bool cmp(const double &a,const double &b){
return a>b;
}

bool check(double mid){
for (int i=0; i<n; i++) tmp[i]=a[i]*100-b[i]*mid;
sort(tmp,tmp+n,cmp);
double summ=0.0;
for (int i=0; i<n-k; i++) summ+=tmp[i];
if (summ>0) return true;
else return false;
}

double solve(){
double low=0,high=100,mid;
while (low+eps<high){
mid=(low+high)/2.0;
if (check(mid)) low=mid;
else high=mid;
}
return mid;
}

int main() {
while (~scanf("%d%d",&n,&k)){
if (n==0 && k==0) break;
for (int i=0; i<n; i++) scanf("%lf",&a[i]);
for (int i=0; i<n; i++) scanf("%lf",&b[i]);
printf("%.0f\n",solve());

}
return 0;
}


#### POJ 2976-Dropping tests(01分数规划_二分||Dinkelbach算法)

2015-08-10 15:00:58

#### POJ2976--Dropping tests

2015-08-22 22:33:24

#### POJ2976 Dropping tests (分数规划)

2015-08-05 16:55:12

#### poj 2976(01分数规划搜索+二分答案)

2012-07-02 17:25:48

#### Dropping tests--计算方法，01分数规划

2016-12-01 14:15:48

#### poj2976(01分数规划)

2015-12-12 17:58:50

#### 【POJ】2976 Dropping tests 01分数规划

2014-07-18 21:51:30

#### POJ 2976 Dropping tests(01分数规划)

2015-05-11 11:21:49

#### [poj 2976]Dropping tests 01分数规划

2014-07-28 20:49:33

#### poj 2976 Dropping tests 01分数规划

2017-04-06 19:00:42