题目连接:10020 - Minimal coverage
题目大意:给出一个范围M,然后给出若干的区间,以0 0 终止, 要求用最少的区间将0 ~M 覆盖,输出最少个数以及方案。
解题思路:典型的区间覆盖问题,算法竞赛入门经典P154上有讲。
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int N = 1000005; struct Seg { int x; int y; }seg[N]; int n, cnt, order, vis[N]; bool cmp (const Seg& a, const Seg& b) { if (a.x != b.x) return a.x < b.x; else return a.y < b.y; } void input() { int p, q; n = cnt = 0; scanf("%d", &order); while (scanf("%d%d", &p, &q), p + q) { seg[n].x = p; seg[n].y = q; n++; } } int main() { int cas; scanf("%d", &cas); while (cas--) { memset(seg, 0, sizeof(seg)); memset(vis, 0, sizeof(vis)); input(); sort(seg, seg + n, cmp); int begin = 0, Max, id; for (int i = 0; i < n; i++) { if (seg[i].x > order) break; Max = 0, id; int k; for (k = 0; k < n - i; k++) { if (seg[i + k].x > begin) { k--; break; } if (seg[i + k].y > Max) { Max = seg[i + k].y; id = i + k; } } if (k > 0) i += k; if (Max < begin) break; begin = Max; vis[cnt++] = id; if (begin >= order) break; } if (Max >= order) { printf("%d\n", cnt); for (int i = 0; i < cnt; i++) printf("%d %d\n", seg[vis[i]].x, seg[vis[i]].y); } else printf("0\n"); if (cas) printf("\n"); } return 0; }