| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
太强了!In Reply To:原装解题报告 Posted by:majia001 at 2006-08-20 12:51:54 > Drop
> ----
>
> This problem was intended to be the hardest problem in the set, and indeed, nobody
> solved it. When choosing to drop tests, there is a trade-off between tests with very
> low percentage scores and tests with mediocre percentage scores but with a large number
> of questions. Which one of these is better can depend on the other tests you are
> keeping. Figuring out how to balance these requirements is the heart of this problem.
>
> The first thing you have to realize is that a simple greedy algorithm is not going
> to be correct. For example, it seems reasonable to drop tests one at a time, always
> choosing to drop the test that will improve your cumulative average by as much as
> possible. However, it turns out this is wrong. For example, consider dropping 2 tests
> from a group of 100/100, 14/50, 14/50, 100/200, and 100/200. The greedy approach would
> first drop a 14/50 test and then a 100/200 test to get a score of 214/350 = 61%, but
> the optimal strategy is to drop both 100/200 tests for a score of 128/200 = 64%.
>
> If you have done a lot of other programming competitions, you might also think of the
> dynamic programming approach (see the stones write-up). By tracking the number of
> questions and the number of tests, you can use this to solve the problem in
> (number of questions)*(number of tests) time. Unfortunately, the maximum number of
> questions over all the tests is a trillion, so that is no good either.
>
> What do you do then? It turns out that the problem can be solved with a binary search.
> We ask the following question: "Can you drop k tests to make your cumulative average
> at least x?". It turns out that fixing x makes the problem substantially easier
> because this is enough to determine which tests are better than others.
>
> If we fix x, we need to choose tests so that
> (sum a_i) / (sum b_i) >= x
> <=> sum a_i >= sum (x*b_i)
> <=> sum (a_i - x*b_i) >= 0.
> Thus, we compute c_i = a_i - x*b_i for each i. We now need to drop k of those values so
> that their sum is at least 0. This is a much easier problem! Just sort the c_i's and
> drop the k smallest values.
>
> This reduces everything to a standard binary search problem. For each x, we can test
> whether we can get an average of at least x, and we need to find the maximum average
> that can be made. C++ code is shown bleow.
>
> double lb = 0, ub = 1;
> for (i = 0; i < 100; i++) {
> double x = (lb+ub)/2;
>
> for (j = 0; j < tests; j++)
> scores[j] = num[j] - x*den[j];
> sort(scores, scores+tests);
> double total = 0;
> for (j = k; j < tests; j++)
> total += scores[j];
>
> if (total >= 0)
> lb = x;
> else
> ub = x;
> }
> cout << int(100*lb + 0.5) << endl;
>
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator