终于把01分数规划这个坑填上了。
题意是有二维平面上的n个向量$(a_i,b_i)$,让你选择其中的m个,使得这些向量和的斜率,即$frac{sum a_i}{sum b_i}$最小。
二分斜率,设$frac{sum a_i}{sum b_i}geqslant k$,即$sum a_igeqslant sum kb_i$,即$sum a_i-kb_igeqslant 0$,选择$a_i-kb_i$前m大的向量判断是否大于0即可。
每次交POJ都得和CE刚上一番...
1 #include<cstdio> 2 #include<functional> 3 #include<algorithm> 4 using namespace std; 5 typedef long long ll; 6 typedef double db; 7 const int N=1000+10,inf=0x3f3f3f3f; 8 int n,k,a[N],b[N]; 9 db c[N]; 10 bool ok(db x) { 11 db sum=0; 12 for(int i=0; i<n; ++i)c[i]=a[i]-x*b[i]; 13 sort(c,c+n,greater<db>()); 14 for(int i=0; i<k; ++i)sum+=c[i]; 15 return sum>=0; 16 } 17 db bi(db l,db r) { 18 for(int i=0; i<100; ++i) { 19 db mid=(l+r)/2; 20 ok(mid)?l=mid:r=mid; 21 } 22 return l; 23 } 24 int main() { 25 while(scanf("%d%d",&n,&k),n) { 26 k=n-k; 27 for(int i=0; i<n; ++i)scanf("%d",&a[i]); 28 for(int i=0; i<n; ++i)scanf("%d",&b[i]); 29 printf("%.0f ",bi(0,1)*100); 30 } 31 return 0; 32 }