简略题意:有n项工作,每项工作有两个属性
先明确主动权在我们手里,对于主席而言理想化的状况就是选了
先按b升序,
现在我们手上有n−(p−k)份工作,我们需要从里面挑出a最大的
然后在剩下的n−k份工作中,找出满足上述加粗部分条件的b尽可能大的若干份工作。需要注意的是,假如被做的工作中有着最小
#define others
#ifdef poj
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#endif // poj
#ifdef others
#include <bits/stdc++.h>
#endif // others
//#define file
#define all(x) x.begin(), x.end()
using namespace std;
const double pi = acos(-1.0);
typedef long long LL;
typedef unsigned long long ULL;
void umax(int &a, int b) {
a = max(a, b);
}
void umin(int &a, int b) {
a = min(a, b);
}
void file() {
freopen("a.in", "r", stdin);
// freopen("1.txt", "w", stdout);
}
namespace Solver {
struct A {
int a, b, id, tag;
} V[110000];
bool cmp1(A x, A y) {
if(x.b != y.b) return x.b < y.b;
return x.a > y.a;
}
bool cmp2(A x, A y) {
if(x.a != y.a) return x.a > y.a;
return x.b > y.b;
}
bool cmp3(A x, A y) {
if(x.b != y.b) return x.b > y.b;
return x.a > y.a;
}
int n, p, k;
void solve() {
scanf("%d%d%d", &n, &p, &k);
for(int i = 1; i <= n; i++) {
int a, b;
scanf("%d%d", &a, &b);
V[i].a = a, V[i].b = b, V[i].id = i, V[i].tag = 0;
}
sort(V + 1, V + 1 + n, cmp1);
sort(V + 1 + p - k, V + 1 + n, cmp2);
int mina = 0x3f3f3f3f, minb = 0x3f3f3f3f;
vector<int> res;
for(int i = p - k + 1; i <= p; i++) {
V[i].tag = 1;
res.push_back(V[i].id);
if(minb > V[i].b) {
minb = V[i].b;
mina = V[i].a;
}
}
sort(V + 1, V + 1 + n , cmp3);
for(int i = 1, cnt = 0; i <= n && cnt < p-k; i++) {
A x = V[i];
if(x.tag == 1) continue;
if(minb == V[i].b && V[i].a < mina) continue;
if(minb >= V[i].b) cnt++, res.push_back(x.id);
}
for(int i = 0; i < res.size(); i++) printf("%d ", res[i]);
}
};
int main() {
// file();
Solver::solve();
return 0;
}