The weight and value of N items are WI and VI. Select K items to maximize the value per unit of weight
Input
N = 3
K = 2
(W, V) = {(2, 2), (5, 3), (2, 1 )}
Output
0.75 (select item 0 and item 2. The average value is (2 + 1)/(2 + 2) = 0.75)
In general, the first thought of method may be to sort items by unit value, from big to small greedy selection. However, the result of this method for the sample is 5/7 = 0.714.
In fact, binary search can be used to solve this problem. We define
Condition C (x): = You can choose to make the unit weight value not less than X
Therefore, the original problem becomes the maximum X that satisfies C (X. Assume that we have selected the set S of an item, and their unit weight value is
ΣVI/Σ WI
Therefore, it becomes to determine whether s meets the following conditions.
ΣVI/Σ WI> = X, that is, Σ (Vi-x * WI)> = 0
Therefore, you can sort (Vi-x * WI) and select it greedy.
C (x) = (Vi-x * WI) the sum of the first K in the ascending to smallest order is not less than 0)
The complexity of each decision is O (nlogn ).
1 # include <iostream> 2 # include <algorithm> 3 # include <cstdio> 4 using namespace STD; 5 6 # define INF 1000 7 # define max_n 1000 8 9 int N, k; 10 int W [max_n], V [max_n]; 11 Double Y [max_n]; 12 13 // determine whether the condition 14 bool C (Double X) is met) 15 {16 for (INT I = 0; I <n; I ++) 17 {18 Y [I] = V [I]-x * W [I]; 19} 20 sort (Y, Y + n); 21 22 // calculate the number of first K and 23 double sum = 0 in the Y array; 24 For (INT I = 0; I <K; I ++) 25 {26 sum + = Y [n-i-1]; 27} 28 return sum> = 0; 29} 30 31 void solve () 32 {33 double lB = 0, UB = inf; 34 for (INT I = 0; I <100; I ++) 35 {36 double mid = (Lb + UB)/2; 37 If (C (MID) lB = mid; 38 else UB = mid; 39} 40 printf ("%. 2f \ n ", UB); 41} 42 43 44 int main () 45 {46 CIN> N> K; 47 for (INT I = 0; I <N; I ++) 48 {49 CIN> W [I]> V [I]; 50} 51 solve (); 52 return 0; 53}
Maximum Average Value