挑戰程序設計競賽 2章習題 poj 2376 Cleaning Shifts
地址 http://poj.org/problem?id=2376

題目大意是 給出 N個區間 ,詢問最小需要選擇幾個區間能覆蓋 1~T的全部區間 第一行輸入 N和 T 后面N行 每行2個數字 表示區間的起點和終點 要求輸出一行 選擇的最小區間個數 若無法覆蓋全部區間 則輸出-1 Sample Input 3 10 1 7 3 6 6 10 Sample Output 2
解法
貪心 將所有區間按照起點排序
選擇能覆蓋當前點且結束最遲的區間 然后更新當前點到選擇的區間最遲的坐標 繼續選擇
本來以為是一個區間覆蓋的模版題,結果wa了一下午,poj沒有數據提,偏偏樣例還能過
看了別人的題解才發現 1~5 6~10居然也算是覆蓋了1~10全區間 這個沒數據真看不出來

對于示例 就是
排序后的區間是 1-7 3-6 6-10
最開始我們需要找到覆蓋坐標1的最優區間 就是1-7
我們取了一個區間 然后找到覆蓋坐標8的最優區間 就是6-10。此時取了兩個區間已經覆蓋了1-10的全部坐標。
答案為2
代碼如下
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <algorithm> #include <stdio.h> using namespace std; const int N = 1000010; /* Sample Input 3 10 1 7 3 6 6 10 Sample Output 2 */ 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", &n, &ed); st = 1; for (int i = 0; i < n; i++) { int l, r; scanf("%d%d", &l, &r); range[i].l = l; range[i].r = 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++; } //如果所有區間都在當前點之前 那就無法覆蓋了 返回-1 跳出 if (r < st) { res = -1; break; } //選擇區間個數加1 res++; //選擇后的所有區間已經覆蓋到終點或者終點之后 那就得到了答案了 if (r >= ed) { success = true; break; } //更新當前點 繼續下一輪尋找可覆蓋的區間 st = r + 1; i = j - 1; } if (!success) res = -1; printf("%d\n", res); return 0; }
作 者: itdef
歡迎轉帖 請保持文本完整并注明出處
技術博客 http://www.rzrgm.cn/itdef/
B站算法視頻題解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
歡迎c c++ 算法愛好者 windows驅動愛好者 服務器程序員溝通交流
如果覺得不錯,歡迎點贊,你的鼓勵就是我的動力
歡迎轉帖 請保持文本完整并注明出處
技術博客 http://www.rzrgm.cn/itdef/
B站算法視頻題解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
歡迎c c++ 算法愛好者 windows驅動愛好者 服務器程序員溝通交流
如果覺得不錯,歡迎點贊,你的鼓勵就是我的動力
浙公網安備 33010602011771號