POJ 2976 Dropping tests
01分数规划,看了这个博客好像懂了一点~
题目大意:
给出n个a和b,让选出n-k个使得(sigma a【i】)/(sigma b【i】)最大
解题思路:
按照01分数规划的正常思路构造D数组,二分求值。
下面是代码:
#include <set> #include <map> #include <queue> #include <math.h> #include <vector> #include <string> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> #define eps 1e-7 #define pi acos(-1.0) #define inf 107374182 #define inf64 1152921504606846976 #define lc l,m,tr<<1 #define rc m + 1,r,tr<<1|1 #define iabs(x) ((x) > 0 ? (x) : -(x)) #define clear1(A, X, SIZE) memset(A, X, sizeof(A[0]) * (SIZE)) #define clearall(A, X) memset(A, X, sizeof(A)) #define memcopy1(A , X, SIZE) memcpy(A , X ,sizeof(X[0])*(SIZE)) #define memcopyall(A, X) memcpy(A , X ,sizeof(X)) #define max( x, y ) ( ((x) > (y)) ? (x) : (y) ) #define min( x, y ) ( ((x) < (y)) ? (x) : (y) ) using namespace std; int n,k; double a[1005],b[1005],t[1005]; double does(double num) { for(int i=0;i<n;i++) { t[i]=a[i]-num*b[i]; } sort(t,t+n); double sum=0.0; for(int i=k;i<n;i++) { sum+=t[i]; } return sum; } int main() { while(scanf("%d%d",&n,&k),n||k) { 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,mid; while(r-l>eps) { mid=(l+r)/2; if(does(mid)>0)l=mid; else r=mid; } printf("%.0f\n",l*100); } return 0; }