數軸上有 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...