传送门
01分数规划板子题啊。
就是简单变形移项就行了。
显然 ∑i=1na[i]∑i=1nb[i]≤k" role="presentation" style="position: relative;">∑ni=1a[i]∑ni=1b[i]≤k∑i=1na[i]∑i=1nb[i]≤k
于是我们二分k。
只需检验:
∑i=1n(a[i]−b[i]∗k)≤0" role="presentation" style="position: relative;">∑ni=1(a[i]−b[i]∗k)≤0∑i=1n(a[i]−b[i]∗k)≤0
代码:
#include<cstdio>
#include<algorithm>
#include<iostream>
#define N 1005
using namespace std;
int n,k;
double c[N],a[N],b[N];
inline bool check(double f){
double ret=0;
for(int i=1;i<=n;++i)c[i]=a[i]-b[i]*f;
sort(c+1,c+n+1);
for(int i=k+1;i<=n;++i)ret+=c[i];
return ret>=0;
}
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
int main(){
while(1){
n=read(),k=read();
if(!n&&!k)break;
for(int i=1;i<=n;++i)a[i]=read();
for(int i=1;i<=n;++i)b[i]=read();
double l=0.0,r=1.0;
while(r-l>1e-10){
double mid=(l+r)*1.0/2.0;
if(check(mid))l=mid;
else r=mid;
}
printf("%.0f\n",l*100);
}
return 0;
}