題意
給出n,k和n對二元組(a,b),要求從中選出n-k個二元組使得
原題鏈接–POJ
題目分析
我們假設答案爲ans,那麼一定對於任意方案有
而
故解在
變一下形就可以得到
若令
於是我們不妨二分
代碼
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define MAXN 1000
#define MAXM
#define INF 0x3f3f3f3f
typedef long long int LL;
template<class T>
void Read(T &x){
x=0;char c=getchar();bool flag=0;
while(c<'0'||'9'<c){if(c=='-')flag=1;c=getchar();}
while('0'<=c&&c<='9'){x=x*10+c-'0';c=getchar();}
if(flag)x=-x;
}
const double EPS = 1e-3;
int Sign(const double x){
if(x>EPS)return 1;
else if(x<-EPS)return -1;
else return 0;
}
bool dcmp(const double &x,const double &y){
return Sign(x-y)>0;
}
double a[MAXN+10],b[MAXN+10];
double d[MAXN+10];
int n,k;
bool check(double l){
for(int i=1;i<=n;++i)
d[i]=a[i]*100.0-l*b[i];
sort(d+1,d+n+1,dcmp);
double sum=0;
for(int i=1;i<=k;++i)
sum+=d[i];
return Sign(sum)>=0;
}
int main(){
while(~scanf("%d%d",&n,&k)){
if(!n&&!k)break;
k=n-k;
for(int i=1;i<=n;++i)scanf("%lf",&a[i]);
for(int i=1;i<=n;++i)scanf("%lf",&b[i]);
double l=0,r=100,mid;
double ans=0;
while(r-l>EPS){
mid=(l+r)/2.0;
if(check(mid)){
ans=max(ans,mid);
l=mid+EPS;
}
else r=mid-EPS;
}
printf("%0.0lf\n",ans);
}
}