题意:给一些工作区间,如何选取最小的工作数量,覆盖[1,T]的工作时长
一开始的思路,当然也是错误的思路:
- 我想着,最小工作数量是吧?那肯定就是选择结束时间最晚的,给结束时间来一个排序。哎这个思路错误的离谱...
解题思路:
- 标记起点,当然对提供的工作区间,按开始的时间从小到大排序。
- 对能够覆盖起点(即可选的工作区域),选择结束时间最晚的(即工作时长最长的)
- 更新起点
代码中的小技巧
主要针对第二个解题思路:
- 可选区域:i<n&&node[i].start<=T+1 --i表示当前循环的工作序号没有超过n,第二个判断语句就是指,当前工作的开始时间小于等于标记的起点+1才可以被选
while(i<n&&node[i].start<=T+1) { end=max(end,node[i].end); i++;}
解题代码:
#include <iostream> #include <algorithm> #include <cstdio> #include <math.h> using namespace std; struct Cow { int b, e; }cow[25001]; int cmp(Cow a, Cow b) { return a.b < b.b; } int main() { int n, t; int ans = 0, T = 0; int i = 0; scanf("%d%d", &n, &t); for (int i = 0; i < n; i++) scanf("%d%d", &cow[i].b, &cow[i].e); sort(cow, cow + n, cmp); while (T<t&&i<n) { ans++; int end = T; if (cow[i].b > T + 1) { break; } else { while (i<n&&cow[i].b <= T + 1) { end = max(end, cow[i].e); i++; } T = end; } if (T >= t) { printf("%d ", ans); return 0; } } if (T >= t) printf("%d ", ans); else printf("-1 "); return 0; }