structRange { int l, r; // 务必掌握 结构体重载运算符 的写法 booloperator< (const Range &W) const { return r < W.r; } }ranges[kN];
intmain(){ int n; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d%d", &ranges[i].l, &ranges[i].r); } sort(ranges, ranges + n); // 别忘sort() int res = 0, ed = -2e9; for (int i = 0; i < n; i++) { if (ed < ranges[i].l) { res++; ed = ranges[i].r; } } printf("%d\n", res); return0; }
AcWing 908. 最大不相交区间数量
难度:简单
题目描述
给定N个闭区间[ai,bi],请你在数轴上选择若干区间,使得选中的区间之间互不相交(包括端点)。
输出可选取区间的最大数量。
输入格式
第一行包含整数N,表示区间数。
接下来N行,每行包含两个整数ai,bi,表示一个区间的两个端点。
输出格式
输出一个整数,表示可选取区间的最大数量。
数据范围
1≤N≤105, −109≤ai≤bi≤109
1 2 3 4 5 6 7 8 9 10
输入样例:
3 -11 24 35
输出样例:
2
贪心
做法与上一题一致。
证明:
ans >= cnt 做法可行,且ans为max的可行
ans <= cnt
z若存在这ans个两两不相交的区间,那么要使得每个区间上至少一个点,至少需要cnt个点,那么cnt >= ans
structRange { int l, r; booloperator< (const Range &W) const { return r < W.r; } }ranges[kN];
intmain(){ int n; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d%d", &ranges[i].l, &ranges[i].r); } sort(ranges, ranges + n); int res = 0, ed = -2e9; for (int i = 0; i < n; i++) { if (ed < ranges[i].l) { res++; ed = ranges[i].r; } } printf("%d\n", res); return0; }
AcWing 906. 区间分组
给定 N 个闭区间 [ai,bi],请你将这些区间分成若干组,使得每组内部的区间两两之间(包括端点)没有交集,并使得组数尽可能小。
structRange { int l, r; booloperator< (const Range &W) const { return l < W.l; } }ranges[kN];
intmain(){ int st, ed; scanf("%d%d", &st, &ed); int n; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d%d", &ranges[i].l, &ranges[i].r); } sort(ranges, ranges + n); int res = 0; bool success = false; for (int i = 0; i < n; i++) { int j = i, r = -2e9; while (j < n && ranges[j].l <= st) { r = max(r, ranges[j].r); j++; } if (r < st) { res = -1; break; } res++; if (r >= ed) { success = true; // 一定要success, 循环结束后可能还没覆盖ed break; } st = r; i = j - 1; } if (!success) res = -1; printf("%d\n", res); return0; }
intmain(){ int n; scanf("%d", &n); priority_queue<int, vector<int>, greater<int>> heap; for (int i = 0; i < n; i++) { int x; scanf("%d", &x); heap.push(x); } longlong res = 0; while (heap.size() > 1) { int a = heap.top(); heap.pop(); int b = heap.top(); heap.pop(); res += (a + b); heap.push(a + b); } printf("%lld\n", res); // %lld return0; }
排序不等式
AcWing 913. 排队打水
有 n 个人排队到 1 个水龙头处打水,第 i 个人装满水桶所需的时间是 ti,请问如何安排他们的打水顺序才能使所有人的等待时间之和最小?
intmain(){ int n; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d", &a[i]); } sort(a, a + n); longlong res = 0; for (int i = 0; i < n; i++) { // 下标为i的第(i+1)个人后会有(n-i-1)个人需要等这个a[i]时间 res += a[i] * (n - i - 1); } printf("%lld\n", res); return0; }
intmain(){ int n; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d", &a[i]); } sort(a, a + n); longlong res = 0; for (int i = 0; i < n; i++) { res += abs(a[i] - a[n >> 1]); } printf("%lld\n", res); return0; }
intmain(){ int n; scanf("%d", &n); for (int i = 0; i < n; i++) { int w, s; scanf("%d%d", &w, &s); cows[i] = {w + s, s}; } sort(cows, cows + n); int res = -2e9, sum = 0; // res初始化要足够小: 最大危险系数可能为大负数 for (int i = 0; i < n; i++) { int w = cows[i].first - cows[i].second, s = cows[i].second; res = max(res, sum - s); sum += w; } printf("%d\n", res); return0; }