題目:區間覆蓋(貪心)
題意:給定 n 個閉區間
[ai,bi]
以及乙個線段區間
[s,t]
,請你選擇盡量少的區間,將指定線段區間完全覆蓋。
輸出最少區間數,如果無法完全覆蓋則輸出 −1。
輸入格式
第一行包含兩個整數 s 和
t,表示給定線段區間的兩個端點。
第二行包含整數 n,表示給定區間數。
接下來 n 行,每行包含兩個整數
ai,bi
,表示乙個區間的兩個端點。
輸出格式
輸出乙個整數,表示所需最少區間數。
如果無解,則輸出 −1。
資料範圍
1≤n≤1e5,
−1e9≤ai≤bi≤1e9,
−1e9≤s≤t≤1e9
輸入樣例:
1 53
-1 3
2 43 5
輸出樣例:
2樣例解釋:
選擇區間[-1, 3]和[3, 5],答案為2。
題目分析:貪心。
解題步驟:
將所有區間按左端點從小到大排序。
設當前要覆蓋的線段的區間是[st, ed],從前往後列舉每個區間,選擇左端點小於等於st且右端點最大的區間,更新要覆蓋的線段的區間,此時答案 + 1;如果沒有左端點小於等於st的區間,則說明無解,輸出-1。
貪心策略證明:
設貪心得到的答案為cnt,本題的正確答案為ans。
由於本題的答案ans是所有方案的最小值,所有必有ans <= cnt。
設在正確答案中有選擇左端點小於等於st,但右端點不是最大的區間。此時,我們將該區間替換成左端點小於等於st,右端點最大的區間是更優的(區間數相同,右端點更大)。故有cnt <= ans。
由於ans <= cnt且cnt <= ans,得cnt = ans。
ac**:
#include
#include
using namespace std;
const int n = 1e5 + 10;
struct sta[n];
int n, st, ed;
void solve(){
scanf("%d %d %d", &st, &ed, &n);
for(int i = 1;i <= n;i++) scanf("%d %d", &a[i].x, &a[i].y);
sort(a + 1, a + 1 + n);
int res = 0, t = st;
for(int i = 1;i <= n;i++){
if(a[i].x <= st) t = max(t, a[i].y);
else{
res++;
if(a[i].x > t){
printf("-1\n");
return;
else{
st = max(a[i].x, t);
t = max(t, a[i].y);
if(t >= ed){
res++;
break;
if(t < ed) res = -1;
printf("%d\n", res);
int main(){
solve();
return 0;
時間複雜度:o(nlogn)。
空間複雜度:o(n)。
貪心 區間覆蓋問題
區間覆蓋問題 time limit 1000ms memory limit 65536kb submit statistic discuss problem description 設x1 x2 xn 是實直線上的n 個點。用固定長度的閉區間覆蓋這n 個點,至少需要多少個這樣的固定長度閉區間?對於給...
區間覆蓋 AcWing 貪心
給定n個閉區間 ai,bi 以及乙個線段區間 s,t 請你選擇盡量少的區間,將指定線段區間完全覆蓋。輸出最少區間數,如果無法完全覆蓋則輸出 1。輸入格式 第一行包含兩個整數s和t,表示給定線段區間的兩個端點。第二行包含整數n,表示給定區間數。接下來n行,每行包含兩個整數ai,bi,表示乙個區間的兩個...
貪心 區間覆蓋(題解)
題意 數軸上有 n 1 n 25000 個閉區間 ai,bi 選擇盡量少的區間覆蓋一條指定線段 1,t 1 t 1,000,000 覆蓋整點,即 1,2 3,4 可以覆蓋 1,4 不可能辦到輸出 1 思路 首先進行預處理,將不在區間 1,t 內的區間砍掉,然後按照左端點從小到大進行排序,當左端點相同...