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