pku 2976 Dropping tests 01分数规划
http://poj.org/problem?id=2976
题意:
给定A数组B数组,从中选择N-K个使得R最大,输出Round(100*R);
思路:
我是根据szz给的这个链接学习的,感觉讲的不错:http://lghjx.573114.com/Blog/Html/103D/275536.html
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <set> #include <map> #include <string> #define CL(a,num) memset((a),(num),sizeof(a)) #define iabs(x) ((x) > 0 ? (x) : -(x)) #define Min(a,b) (a) > (b)? (b):(a) #define Max(a,b) (a) > (b)? (a):(b) #define ll long long #define inf 0x7f7f7f7f #define MOD 1073741824 #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define test puts("<------------------->") #define maxn 100007 #define M 150 #define N 10007 using namespace std; //freopen("din.txt","r",stdin); double a[N],b[N],d[N]; const double eps = 1e-6; int n,k; int cmp(int a,int b) { return a > b; } int dblcmp(double x) { if (x > eps) return 1; else if (x < -eps) return -1; else return 0; } int main() { int i; while (~scanf("%d%d",&n,&k)) { if (!n && !k) break; for (i = 0; i < n; ++i) scanf("%lf",&a[i]); for (i = 0; i < n; ++i) scanf("%lf",&b[i]); double r = -1.0; for (i = 0; i < n; ++i) { if (a[i]/b[i] > r) r = a[i]/b[i]; } int m = n - k; double l = 0; double ans = 0; while (dblcmp(l - r) < 0) { double mid = (l + r)/2.0; for (i = 0; i < n; ++i) d[i] = a[i] - mid*b[i]; sort(d,d + n,cmp); // reverse(a,a + n); double tmp = 0; for (i = 0; i < m; ++i) tmp += d[i]; if (tmp >= 0) { ans = mid; l = mid; } else r = mid; } printf("%.0lf\n",ans*100); } return 0; }