There are two weight values (a and B) for each nheaded ox. Select the C Ox from the N ox so that:
1. The median of a weights of these cattle should be as large as possible.
2. The B weights of these cattle are less than F given in the question
Output the median of the largest a weight. If the solution of the question is not satisfied, output-1. Value.
Ideas:
Heap has a magical function. Suppose it is an array. When B moves from A to C, a large root heap can be used to maintain B at all positions, select the minimum sum of K values from A to B and obtain the answer within nlogn.
The method is as follows: first add the elements of [a, A + k] to a large root heap and record their sum. Then let B keep repeating backward, add B to the big root heap, sum + = B, and take out the maximum value in the big root heap, Sum-= max.
The sum value is the largest sum of K Elements in [a, B], because the elements in the heap are the smallest k numbers in [a, B, sum is the sum of the number in the heap.
This method can be used to solve this problem.
First, sort the input data in descending order of a weight. The array is scanned from left to right, And the array is scanned from right to left. A sum array is recorded. sum [I] indicates that when I is used as the median of a weight, the minimum values of the B weight and the B weight (not included in the user ). Finally, I scanned it from the back to the back and enumerated the number of the I-th ox as the median of the weight, when sum [I] is added with its own a weight less than or equal to F, the answer is output.
Code:
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MAX 1000000using namespace std;struct Complex{int x,y;bool operator <(const Complex &a)const {return x < a.x;}}cow[MAX];struct BigHeap{int num[MAX],last;int Top() {return num[1];}void Insert(int x) {num[++last] = x;int now = last;while(num[now] > num[now >> 1] && now > 1)swap(num[now],num[now >> 1]),now >>= 1;}void Pop() {num[1] = num[last--];int now = 2;while(now <= last) {if(num[now] < num[now + 1])now++;if(num[now] > num[now >> 1])swap(num[now],num[now >> 1]),now <<= 1;elsebreak;}}void Clear() {last = 0;}}heap;int points,select,limit;int sum[MAX];int main(){cin >> select >> points >> limit;for(int i = 1;i <= points; ++i)scanf("%d%d",&cow[i].x,&cow[i].y);sort(cow + 1,cow + points + 1);select >>= 1;int temp = 0;for(int i = 1;i <= select; ++i) {temp += cow[i].y;heap.Insert(cow[i].y);}sum[select + 1] = temp;for(int i = select + 1;i < points; ++i) {heap.Insert(cow[i].y);temp += cow[i].y;temp -= heap.Top();heap.Pop();sum[i + 1] = temp;}temp = 0,heap.Clear();for(int i = points;i > points - select; --i) {temp += cow[i].y;heap.Insert(cow[i].y);}sum[points - select] += temp;for(int i = points - select;i >= select; --i) {heap.Insert(cow[i].y);temp += cow[i].y;temp -= heap.Top();heap.Pop();sum[i - 1] += temp;}int ans = -1;for(int i = points - select;i >= select + 1; --i)if(sum[i] + cow[i].y <= limit) {ans = cow[i].x;break;}cout << ans << endl;return 0;}
Poj 2010 advanced application of moo University-financial aid heap-minimum maintenance (max sum)