学习了lyd书上的0/1分数规划,发现这类题目都有一个特点,就是求$\frac{\sum_{a_{i}*x_{i}}}{\sum_{b_{i}*x_{i}}}$的最大或者最小,再加一些限制取不取的条件.
二分答案+sort取前(n-k+1)个。
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> using namespace std; const int maxn = 1e3 + 50; int a[maxn], b[maxn]; double diff[maxn]; int n, k; int check(double x) { for(int i = 1; i <= n; i++) { diff[i] = (double)a[i] - x * b[i]; } sort(diff + 1, diff + n + 1); double ans = 0; for(int i = n; i >= k + 1; i--) { ans += diff[i]; } if(ans >= 0.0 || fabs(ans) <= (1e-8)) return 1; else return 0; } int main() { while(scanf("%d %d", &n, &k) != EOF && (n || k)) { for(int i = 1; i <= n; i++) scanf("%d", &a[i]); for(int i = 1; i <= n; i++) scanf("%d", &b[i]); double ans = 0; double l = 0, r = 1; int T = 100; while(T--) { double mid = (l + r) / 2.0; if(check(mid)) { // printf("%f\n", mid); ans = mid; l = mid; } else { r = mid; } } printf("%.f\n", 100.0 * ans); } return 0; }