「bsoj4498」玩具 - 贪心 | Bill Yang's Blog

「bsoj4498」玩具 - 贪心

题目大意


题目分析

又是一道比较神奇的贪心。

首先二分答案应该是比较容易想到的。

二分答案后转为判定性问题。
开始想了一个错误的贪心思路:一个机器人肯定选取比自己小的更大的$mid$个元素
这个思路看似正确,但因为有两个属性的影响,重量较小的可能体积更大,舍弃了这些较小的有可能使得该物品无法选取从而判断失误。

因此得出另一个贪心思路,优先选取重量比自己小的体积最大的$mid$个元素,这样便能保证最优。

那么我们用一个大根堆来维护决策。

最后需要卡卡常数才能过,所以说二分上界与$10000$取了个$\min$。


代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
inline const int Get_Int() {
int num=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
num=num*10+x-'0';
x=getchar();
}
return num*bj;
}
struct Thing {
int w,s;
bool operator < (const Thing& b) const {
return w<b.w;
}
} t[1000005];
int n,A,B,a[50005],b[50005];
bool Check(int mid) {
priority_queue<int>Q;
int j=1;
for(int i=1; i<=A; i++) {
while(j<=n&&t[j].w<a[i])Q.push(t[j++].s);
int cnt=mid;
while(cnt>0&&!Q.empty()) {
Q.pop();
cnt--;
}
}
while(j<=n)Q.push(t[j++].s);
for(int i=B; i>=1; i--) {
int cnt=mid;
while(cnt>0&&!Q.empty()&&Q.top()<b[i]) {
Q.pop();
cnt--;
}
}
return Q.empty();
}
int main() {
n=Get_Int();
A=Get_Int();
B=Get_Int();
for(int i=1; i<=A; i++)a[i]=Get_Int();
for(int i=1; i<=B; i++)b[i]=Get_Int();
for(int i=1; i<=n; i++) {
t[i].w=Get_Int();
t[i].s=Get_Int();
}
sort(a+1,a+A+1);
sort(b+1,b+B+1);
sort(t+1,t+n+1);
int Left=0,Right=min(n,10000);
while(Left<=Right) {
int mid=(Left+Right)>>1;
if(Check(mid))Right=mid-1;
else Left=mid+1;
}
if(Left==n+1)puts("-1");
else printf("%d\n",Left);
return 0;
}
本篇文章有用吗?有用还不快点击!
0%