贪心算法的一些模板
贪心
区间选点
给定 N 个闭区间 [a,b],请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。输出选择的点的最小数量。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef pair<int, int> PII;
vector<PII> segs;
int main(void) {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
int l, r;
scanf("%d%d", &l, &r);
segs.push_back({r, l});
}
sort(segs.begin(), segs.end());
int res = 0;
int t = -2e9;
for (auto it : segs) {
int l = it.second, r = it.first;
if (t < l) {
t = r;
res++;
}
}
cout << res;
return 0;
}
最大不相交区间数量
给定 N 个闭区间 [a,b],请你在数轴上选择若干区间,使得选中的区间之间互不相交(包括端点)。输出可选取区间的最大数量。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef pair<int, int> PII;
vector<PII> segs;
int main(void) {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
int l, r;
scanf("%d%d", &l, &r);
segs.push_back({r, l});
}
sort(segs.begin(), segs.end());
int res = 0;
int t = -2e9;
for (auto it : segs) {
int l = it.second, r = it.first;
if (t < l) {
t = r;
res++;
}
}
cout << res;
return 0;
}
区间分组
给定 N 个闭区间 [a,b],请你将这些区间分成若干组,使得每组内部的区间两两之间(包括端点)没有交集,并使得组数尽可能小。
输出最小组数。
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#define l first
#define r second
using namespace std;
typedef pair<int, int> PII;
int main(void) {
int n;
scanf("%d", &n);
vector<PII> segs;
for (int i = 1; i <= n; ++i) {
int l ,r;
scanf("%d%d", &l, &r);
segs.push_back({l, r});
}
sort(segs.begin(), segs.end());
priority_queue<int, vector<int>, greater<int>> heap;
for (PII t : segs) {
if (heap.size() == 0 || heap.top() >= t.l) heap.push(t.r);
else {
heap.pop();
heap.push(t.r);
}
}
cout << heap.size();
return 0;
}
区间覆盖
给定 N 个闭区间 [ai,bi]以及一个线段区间 [s,t],请你选择尽量少的区间,将指定线段区间完全覆盖。
输出最少区间数,如果无法完全覆盖则输出 −1。
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
struct Node {
int l, r;
bool operator< (const Node &t) const {
return l < t.l;
}
} segs[N];
int main(void) {
int st, ed;
scanf("%d%d", &st, &ed);
int n;
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d%d", &segs[i].l, &segs[i].r);
}
sort(segs + 1, segs + n + 1);
int flag = false;
int res = 0;
for (int i = 1; i <= n; ++i) {
int j = i, r = -2e9;
while (j <= n && segs[j].l <= st) {
r = max(r, segs[j].r);
j++;
}
if (r < st) break;
res++;
if (r >= ed) {
flag = true;
break;
}
st = r;
i = j - 1;
}
if (!flag) res = -1;
cout << res;
return 0;
}
Huffman树
#include <iostream>
#include <queue>
using namespace std;
int main(void) {
priority_queue<int, vector<int>, greater<int>> heap;
int n;
cin >> n;
while (n--) {
int x;
cin >> x;
heap.push(x);
}
int sum = 0;
while (heap.size() > 1) {
int a = heap.top(); heap.pop();
int b = heap.top(); heap.pop();
sum += a + b;
heap.push(a + b);
}
cout << sum;
return 0;
}