链接:http://poj.org/problem?id=2976
题意:给你n个a和b,让你求删掉其中的k对使得 sigma(a[i])/sigma(b[i])最大。
分析:01分数规划第一题,看这篇可以有个大概的了解。关键点在于不容易求一个值,但是验证某个值可行很容易。
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define Mn 1010
#define Mm 2000005
#define mod 1000000007
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define CLRS(a,b,Size) memset((a),(b),sizeof((a[0]))*(Size+1))
#define CPY(a,b) memcpy ((a), (b), sizeof((a)))
#pragma comment(linker, "/STACK:102400000,102400000")
#define ul u<<1
#define ur (u<<1)|1
#define eps 1e-5
using namespace std;
typedef long long ll;
double a[Mn],b[Mn],d[Mn];
int n,m;
bool check(double x) {
double sum=0;
for(int i=0;i<n;i++) d[i]=a[i]-x*b[i];
sort(d,d+n);
for(int i=m;i<n;i++) sum+=d[i];
if(sum>0) return true;
else return false;
}
int main() {
while(~scanf("%d%d",&n,&m)) {
if(n==0&&m==0) break;
for(int i=0;i<n;i++) {
scanf("%lf",&a[i]);
}
for(int i=0;i<n;i++) {
scanf("%lf",&b[i]);
}
double l=0.0,r=1.0;
while(l+eps<r) {
double mid=(l+r)/2;
if(check(mid)) l=mid;
else r=mid;
}
printf("%.0f\n",100*l);
}
return 0;
}