[POJ2976]Dropping tests(01分数规划,二分)
题目链接:http://poj.org/problem?id=2976
题意:你有n个成绩要从中删除k个,使得100*(∑ai/∑bi)值最大。
这是个简单的01分数规划题,关于01分数规划:http://www.cnblogs.com/perseawe/archive/2012/05/03/01fsgh.html。
通过数学分析获得一个目标式的变形后,可以知道F(L)=∑ai*xi-L*∑bi*xi,使F(L)=0就是使L最大化。我们枚举L后获得ai*xi-L*bi*xi的值,对这个值从大到小排序,再去算前n-k个的∑ai*xi和∑bi*xi,看看∑ai*xi/∑bi*xi是否大于二分得到的L,如果大于则更新左值,否则更新右值。
1 /* 2 ━━━━━┒ギリギリ♂ eye! 3 ┓┏┓┏┓┃キリキリ♂ mind! 4 ┛┗┛┗┛┃\○/ 5 ┓┏┓┏┓┃ / 6 ┛┗┛┗┛┃ノ) 7 ┓┏┓┏┓┃ 8 ┛┗┛┗┛┃ 9 ┓┏┓┏┓┃ 10 ┛┗┛┗┛┃ 11 ┓┏┓┏┓┃ 12 ┛┗┛┗┛┃ 13 ┓┏┓┏┓┃ 14 ┃┃┃┃┃┃ 15 ┻┻┻┻┻┻ 16 */ 17 #include <algorithm> 18 #include <iostream> 19 #include <iomanip> 20 #include <cstring> 21 #include <climits> 22 #include <complex> 23 #include <fstream> 24 #include <cassert> 25 #include <cstdio> 26 #include <bitset> 27 #include <vector> 28 #include <deque> 29 #include <queue> 30 #include <stack> 31 #include <ctime> 32 #include <set> 33 #include <map> 34 #include <cmath> 35 using namespace std; 36 #define fr first 37 #define sc second 38 #define cl clear 39 #define BUG puts("here!!!") 40 #define W(a) while(a--) 41 #define pb(a) push_back(a) 42 #define Rint(a) scanf("%d", &a) 43 #define Rs(a) scanf("%s", a) 44 #define Cin(a) cin >> a 45 #define FRead() freopen("in", "r", stdin) 46 #define FWrite() freopen("out", "w", stdout) 47 #define Rep(i, len) for(int i = 0; i < (len); i++) 48 #define For(i, a, len) for(int i = (a); i < (len); i++) 49 #define Cls(a) memset((a), 0, sizeof(a)) 50 #define Clr(a, x) memset((a), (x), sizeof(a)) 51 #define Full(a) memset((a), 0x7f7f7f, sizeof(a)) 52 #define lrt rt << 1 53 #define rrt rt << 1 | 1 54 #define pi 3.14159265359 55 #define RT return 56 #define lowbit(x) x & (-x) 57 #define onecnt(x) __builtin_popcount(x) 58 typedef long long LL; 59 typedef long double LD; 60 typedef unsigned long long ULL; 61 typedef pair<int, int> pii; 62 typedef pair<string, int> psi; 63 typedef pair<LL, LL> pll; 64 typedef map<string, int> msi; 65 typedef vector<int> vi; 66 typedef vector<LL> vl; 67 typedef vector<vl> vvl; 68 typedef vector<bool> vb; 69 inline bool scan_d(LL &num) { 70 char in;bool IsN=false; 71 in=getchar(); 72 if(in==EOF) return false; 73 while(in!='-'&&(in<'0'||in>'9')) in=getchar(); 74 if(in=='-'){ IsN=true;num=0;} 75 else num=in-'0'; 76 while(in=getchar(),in>='0'&&in<='9'){ 77 num*=10,num+=in-'0'; 78 } 79 if(IsN) num=-num; 80 return true; 81 } 82 83 const double eps = 1e-9; 84 const int maxn = 1010; 85 int n, k, m; 86 LL a[maxn], b[maxn]; 87 pair<double, int> d[maxn]; 88 89 bool ok(double x) { 90 For(i, 1, n+1) d[i].first = a[i] - x * b[i], d[i].second = i; 91 sort(d+1, d+n+1, greater<pair<double, int> >()); 92 double ta = .0, tb = .0; 93 For(i, 1, n-k+1) { 94 ta += a[d[i].second]; 95 tb += b[d[i].second]; 96 } 97 return ta / tb >= x; 98 } 99 100 int main() { 101 // FRead(); 102 while(~Rint(n) && ~Rint(k) && n + k) { 103 For(i, 1, n+1) scan_d(a[i]); 104 For(i, 1, n+1) scan_d(b[i]); 105 double lo = 0, hi = 1; 106 while(hi - lo > eps) { 107 double mid = (lo + hi) / 2; 108 if(ok(mid)) lo = mid; 109 else hi = mid; 110 } 111 cout << fixed << setprecision(0) << lo * 100 << endl; 112 } 113 RT 0; 114 }