while(l<r){
int mid=l+r>>1;
if(check(mid)) l=mid+1;
else r=mid;
}
int mid=l+r+1>>1;
if(check(mid)) l=mid;
else r=mid-1;
}
不管咋样,都是这两种格式。记住就好。然后具体用哪一个,按照实际情况来。实数二分同样如此,只不过1变成了eps。一般直接for循环100次就好,精度肯定够用了。 0/1分数规划:简化成这样一个问题:给定你了
n
n
n 对
a
i
,
b
i
,
a_i,b_i,
a i , b i , 给了你一个
k
k
k ,让你从中选出
k
k
k 对,让
∑
i
=
1
k
a
i
∑
i
=
1
k
b
i
\frac{\sum_{i=1}^{k}a_i}{\sum_{i=1}^{k}bi}
∑ i = 1 k b i ∑ i = 1 k a i 最大。很明显,答案具有单调性。可以二分答案,然后每次判断是否符合条件就ok
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=1e3+10;
int n,m;double a[N],b[N];
double c[N];
bool check(double L){
for(int i=1;i<=n;++i) c[i]=a[i]-b[i]*L;
//cout<<endl;
sort(c+1,c+n+1);
double ans=0;
for(int i=n;i>m;--i) ans+=c[i];
if(ans>=0) return 1;
else return 0;
}
int main(){
while(1){
scanf("%d%d",&n,&m);
if(!n&&!m) break;
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=0x3f3f3f3f;
while(l+0.00001<r){
double mid=(l+r+0.00001)/2;
if(check(mid)) l=mid;
else r=mid-0.00001;
}
printf("%.0lf\n",r*100);
}
return 0;
}