贪心算法
区间选点
/* 给定N个闭区间[ai,bi],请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。输出选择的点的最小数量。位于区间端点上的点也算作区间内。*/ const int N = 100010; int n; struct Range { int l, r; bool operator< (const Range &W)const { return r < W.r; } }range[N]; int main() { scanf("%d", &n); for (int i = 0; i < n; i ++ ) scanf("%d%d", &range[i].l, &range[i].r); sort(range, range + n); int res = 0, ed = -2e9; for (int i = 0; i < n; i ++ ) if (range[i].l > ed) { res ++ ; ed = range[i].r; } printf("%d\n", res); return 0; }
最大不相交区间
/* 给定N个闭区间[ai,bi],请你在数轴上选择若干区间,使得选中的区间之间互不相交(包括端点)。输出可选取区间的最大数量。 */ const int N = 100010; int n; struct Range { int l, r; bool operator< (const Range &W)const { return r < W.r; } }range[N]; int main() { scanf("%d", &n); for (int i = 0; i < n; i ++ ) scanf("%d%d", &range[i].l, &range[i].r); sort(range, range + n); int res = 0, ed = -2e9; for (int i = 0; i < n; i ++ ) if (ed < range[i].l) { res ++ ; ed = range[i].r; } printf("%d\n", res); return 0; }
区间分组
/* 给定N个闭区间[ai,bi],请你将这些区间分成若干组,使得每组内部的区间两两之间(包括端点)没有交集,并使得组数尽可能小。*/ const int N = 100010; int n; struct Range { int l, r; bool operator< (const Range &W)const { return l < W.l; } }range[N]; int main() { scanf("%d", &n); for (int i = 0; i < n; i ++ ) { int l, r; scanf("%d%d", &l, &r); range[i] = {l, r}; } sort(range, range + n); priority_queue<int, vector<int>, greater<int>> heap; for (int i = 0; i < n; i ++ ) { auto r = range[i]; if (heap.empty() || heap.top() >= r.l) heap.push(r.r); else { heap.pop(); heap.push(r.r); } } printf("%d\n", heap.size()); return 0; }
区间覆盖
/*给定N个闭区间[ai,bi]以及一个线段区间[s,t],请你选择尽量少的区间,将指定线段区间完全覆盖。输出最少区间数,如果无法完全覆盖则输出-1。*/ const int N = 100010; int n; struct Range { int l, r; bool operator< (const Range &W)const { return l < W.l; } }range[N]; int main() { int st, ed; scanf("%d%d", &st, &ed); scanf("%d", &n); for (int i = 0; i < n; i ++ ) { int l, r; scanf("%d%d", &l, &r); range[i] = {l, r}; } sort(range, range + n); int res = 0; bool success = false; for (int i = 0; i < n; i ++ ) { int j = i, r = -2e9; while (j < n && range[j].l <= st) { r = max(r, range[j].r); j ++ ; } if (r < st) { res = -1; break; } res ++ ; if (r >= ed) { success = true; break; } st = r; i = j - 1; } if (!success) res = -1; printf("%d\n", res); return 0; }
排队打水
/*有 n 个人排队到 1 个水龙头处打水,第 i 个人装满水桶所需的时间是 ti,请问如何安排他们的打水顺序才能使所有人的等待时间之和最小?*/ typedef long long LL; const int N = 100010; int n; int t[N]; int main() { scanf("%d", &n); for (int i = 0; i < n; i ++ ) scanf("%d", &t[i]); sort(t, t + n); reverse(t, t + n); LL res = 0; for (int i = 0; i < n; i ++ ) res += t[i] * i; printf("%lld\n", res); return 0; }
货仓选址
/*在一条数轴上有 N 家商店,它们的坐标分别为 A1…AN。A1…AN。现在需要在数轴上建立一家货仓,每天清晨,从货仓到每家商店都要运送一车商品。为了提高效率,求把货仓建在何处,可以使得货仓到每家商店的距离之和最小。*/ const int N = 100010; int n; int q[N]; int main() { scanf("%d", &n); for (int i = 0; i < n; i ++ ) scanf("%d", &q[i]); sort(q, q + n); int res = 0; for (int i = 0; i < n; i ++ ) res += abs(q[i] - q[n / 2]); printf("%d\n", res); return 0; }
耍杂技的牛
/*农民约翰的N头奶牛(编号为1..N)计划逃跑并加入马戏团,为此它们决定练习表演杂技。奶牛们不是非常有创意,只提出了一个杂技表演:叠罗汉,表演时,奶牛们站在彼此的身上,形成一个高高的垂直堆叠。 奶牛们正在试图找到自己在这个堆叠中应该所处的位置顺序。这N头奶牛中的每一头都有着自己的重量Wi以及自己的强壮程度Si。一头牛支撑不住的可能性取决于它头上所有牛的总重量(不包括它自己)减去它的身体强壮程度的值,现在称该数值为风险值,风险值越大,这只牛撑不住的可能性越高。您的任务是确定奶牛的排序,使得所有奶牛的风险值中的最大值尽可能的小。*/ typedef pair<int, int> PII; const int N = 50010; int n; PII cow[N]; int main() { scanf("%d", &n); for (int i = 0; i < n; i ++ ) { int s, w; scanf("%d%d", &w, &s); cow[i] = {w + s, w}; } sort(cow, cow + n); int res = -2e9, sum = 0; for (int i = 0; i < n; i ++ ) { int s = cow[i].first - cow[i].second, w = cow[i].second; res = max(res, sum - s); sum += w; } printf("%d\n", res); return 0; }
知识点和代码均学习于Acwing: https://www.acwing.com/activity/
来源:https://www.cnblogs.com/recoverableTi/p/12248061.html