POJ 2376题目大意如下:
有N头牛要在指定的T时间以内工作,但是每头牛的工作时间区间给定了,同时在1~T这T个小时里面,每个小时都至少得有一头牛在工作,如果这种情况不恒成立,那么输出“-1”说明没有解决方案,否则,给出最佳解决方案:使用最少牛的头数
观察到问题的规模并不大,所以可以用暴力搜索来做,但是要注意的一点是:在对这N头牛按照它们的工作时段来排序之后(我的排序是按照先排下限,在下限相等时候再排上限)。所以我开始给出这么一个短路判定:
if (cow[0].left != 1 || cow[N - 1].right < T) printf("-1\n");
然而就是这么一句话,弄得自己提交了不下十次,才发现问题所在:既然排序是在如上所说的情况之下,所以“ cow[N - 1].right < T ”这句话是错误的,因为最后一个时间段的上限不大于等于T,不说明之前的时间段上限不能达到这个值。
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int max2 = 25000;
struct Section{ int left, right; };
Section cow[max2 + 1];
int N, T;
bool comp(const Section& lhs, const Section& rhs) {
return lhs.left < rhs.left || (lhs.left == rhs.left && lhs.right < rhs.right);
}
void solve() {
//如果不是从1开始
if (cow[0].left != 1) printf("-1\n");
else {
int i = 0, sum = 1;
Section flag = cow[0]; //用来作为断定不同牛的一个时间短标准
while (i < N) {
int j = i + 1, temp = 0;
//找到工作时间段最大的那头牛,前提是它的开始时间在上一头牛的时间段以内,而它的结束时间大于上一头牛的结束时间
while (j < N) {
if (cow[j].left > flag.right + 1) break;
else if (cow[j].right > flag.right) {
if (cow[temp].right < cow[j].right) temp = j;
}
j++;
}
if (temp != 0) {
flag = cow[temp];
sum++;
i = temp;
}
else i++;
}
if (flag.right >= T) printf("%d\n", sum);
else printf("-1\n");
}
}
int main(int argc, const char * argv[]) {
// insert code here...
scanf("%d %d", &N, &T);
for (int i = 0; i < N; i++) scanf("%d %d", &cow[i].left, &cow[i].right);
sort(cow, cow + N, comp);
solve();
return 0;
}
Accept 880K / 63MS