區間覆蓋(貪心)

2022-09-19 09:15:11 字數 1780 閱讀 2822

題目:區間覆蓋(貪心)

題意:給定 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 內的區間砍掉,然後按照左端點從小到大進行排序,當左端點相同...