您的位置:首页 > 其它

codeforces 332C Students' Revenge 贪心

2018-03-08 15:55 369 查看
简略题意:有n项工作,每项工作有两个属性a和b,代表如果主席接受了这份工作,就要长a根白头发,不接受董事会就要有b的不满意度。我们需要从n项工作里挑出p项工作使得主席的白头发尽可能多,多种方案选董事会最不满意的那个方案。而主席从p份工作里挑k个工作,首先使得董事会满意,多种方案选取自己白头发最少的方案。

先明确主动权在我们手里,对于主席而言理想化的状况就是选了b最小的p−k份工作,然后不做,并且这p−k份工作的a值还很大。所以我们尽可能让这p−k份工作不会被选上。

先按b升序,a降序排序,去除掉前p−k份工作。

现在我们手上有n−(p−k)份工作,我们需要从里面挑出a最大的k份工作给主席做,并且为了保证这几份工作一定会被做,我们还要确保这几份工作里面b的最小值也要大于等于没被做的工作的最大值。

然后在剩下的n−k份工作中,找出满足上述加粗部分条件的b尽可能大的若干份工作。需要注意的是,假如被做的工作中有着最小b值的(ai,bi),和我们当前准备不做的工作(aj,bj)满足bi==bj且ai<aj,那么我们就不能选这份工作,因为如果选上了这份工作,他们的关系就会交换,那么就不能保证∑a是最大的了。

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: