區間選點 Gym 270437B

2021-10-03 20:43:46 字數 1312 閱讀 4502

數軸上有 n 個閉區間 [a_i, b_i]。取盡量少的點,使得每個區間內都至少有乙個點(不同區間內含的點可以是同乙個)input第一行1個整數n(n<=100)

第2~n+1行,每行兩個整數a,b(a,b<=100)output乙個整數,代表選點的數目examples

input

21 5

4 6output

1input

31 3

2 54 6

output

2區間選點問題,以最少的點數實現每個區間裡都有至少有乙個點被選入其中,可以採用貪心的思想,將每個區間按照右端點的位置排序,然後從第乙個右端點開始,選擇這個右端點,然後將所有區間,只要是區間內有這個點,就將這個區間刪除,當所有符合條件的區間全被刪除之後,只要還存在區間,則從剩下的區間中選擇右端點最小的區間,選其右端點,繼續操作即可。

關於這個演算法的證明可以採用交換證明的方法,即將乙個最優解轉化為貪心解,解沒有變差。假設a1,a2,a3…an是我們求出的貪心解,o1,o2,o3…on是最優解,且a1到a(i-1)和o1到o(i-1)是完全一樣的,而ai != oi,那麼一定存在乙個區間[x , y]滿足a(i-1) < x而ai == y,則這時候oi < ai,因為ai是在這個區間內的最右邊的點,oi為了能在這個區間內,只能小於ai,而ai靠右有屬於更多區間的機會,因此ai優於oi,貪心解不會更差。

這道選點題最重要的是思考出貪心演算法該貪什麼,按照題目的意思,乙個區間內的兩個點右邊的點存在於更多區間內的可能性更大,這是關鍵,將右端點按從小到大排序,貪右端點。

#include

#include

#include

using

namespace std;

struct section //代表區間的結構體

section

(const section &m):a

(m.a),b

(m.b)};

intmain()

sort

(sec.

begin()

, sec.

end(),

(section& p1, section& p2)

->

bool);

//按右端點從小到大排序

int dots =0;

while

(sec.

size()

!=0)else it++;}

} cout << dots;

}

Gym 270437B 區間選點

區間選點 數軸上有 n 個閉區間 a i,b i 取盡量少的點,使得每個區間內都至少有乙個點 不同區間內含的點可以是同乙個 input 第一行1個整數n n 100 第2 n 1行,每行兩個整數a,b a,b 100 output 乙個整數,代表選點的數目 解題思路 定義乙個結構體,把每個區間的左右...

B 區間選點

數軸上有 n 個閉區間 a i,b i 取盡量少的點,使得每個區間內都至少有乙個點 不同區間內含的點可以是同乙個 第一行1個整數n n 100 第2 n 1行,每行兩個整數a,b a,b 100 乙個整數,代表選點的數目。input 21 5 4 6output 1input 31 3 2 54 6...

B 區間選點

數軸上有 n 個閉區間 a i,b i 取盡量少的點,使得每個區間內都至少有乙個點 不同區間內含的點可以是同乙個 input 第一行1個整數n n 100 第2 n 1行,每行兩個整數a,b a,b 100 output 乙個整數,代表選點的數目examples input 2 1 54 6outp...