1214线段覆盖问题——贪心法
題目描述:
給定x軸上的N(0<N<100)條線段,每個(gè)線段由它的二個(gè)端點(diǎn)a_I和b_I確定,I=1,2,……N.這些坐標(biāo)都是區(qū)間(-999,999)的整數(shù)。有些線段之間會(huì)相互交疊或覆蓋。請(qǐng)你編寫一個(gè)程序,從給出的線段中去掉盡量少的線段,使得剩下的線段兩兩之間沒有內(nèi)部公共點(diǎn)。所謂的內(nèi)部公共點(diǎn)是指一個(gè)點(diǎn)同時(shí)屬于兩條線段且至少在其中一條線段的內(nèi)部(即除去端點(diǎn)的部分)。
輸入描述:
輸入第一行是一個(gè)整數(shù)N。接下來(lái)有N行,每行有二個(gè)空格隔開的整數(shù),表示一條線段的二個(gè)端點(diǎn)的坐標(biāo)。?
輸出描述:
輸出第一行是一個(gè)整數(shù)表示最多剩下的線段數(shù)。
樣例輸入:
3
6? 3
1? 3
2? 5
樣例輸出:
2
數(shù)據(jù)范圍及提示:
0<N<100
貪心法:
該線段覆蓋問(wèn)題其實(shí)本質(zhì)上是貪心算法里面的最大不相交覆蓋問(wèn)題。根據(jù)題意,我們需要最多的線段,所以對(duì)于每一條右端點(diǎn)相同的線段,選長(zhǎng)度小的;至于為什么要選右端點(diǎn)作升序排列?我還不是特別能夠理解,最好就是列出具體的線段去比較左端點(diǎn)排列和右端點(diǎn)排列的區(qū)別。當(dāng)使用右端點(diǎn)升序時(shí),你僅僅需要考慮前面那條線段(前者)的右端點(diǎn)是否比后面那條線段(后者)的左端點(diǎn)小即可,而使用左端點(diǎn)升序時(shí),則還需要考慮更多。似乎用貪心的最優(yōu)子結(jié)構(gòu)是可以解釋的,有大佬能解釋就幫忙解釋一下,謝謝。
#include<iostream> using namespace std; int main() {int n,t;int left[101],right[101];cin>>n; //輸入線段并調(diào)整線段的左右端點(diǎn),簡(jiǎn)單地交換for(int i=0;i<n;i++){cin>>left[i]>>right[i];if(left[i]>right[i]){t=left[i];left[i]=right[i];right[i]=t;}} //令線段按右端點(diǎn)升序排列,使用冒泡排序for(int i=0;i<n-1;i++){for(int j=0;j<n-i-1;j++){if(right[j]>right[j+1]){t=left[j];left[j]=left[j+1];left[j+1]=t;t=right[j];right[j]=right[j+1];right[j+1]=t;}}} //統(tǒng)計(jì)符合條件的線段數(shù)int j=0,sum=1;for(int i=1;i<n;i++){if(left[i]>=right[j]){sum++;j=i;}}cout<<sum;return 0; }?
總結(jié)
以上是生活随笔為你收集整理的1214线段覆盖问题——贪心法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: +AI场景,3步懂图像识别产品
- 下一篇: 史上最烂 spring aop 原理分析