區間選點+區間覆蓋,區間選點覆蓋
區間選點+區間覆蓋
區間選點問題(選擇最少的點,使得每個區間都至少有k個點)
將這些區間[l,r]先按照r從小到大排序,再按照l從大到小排序。選點盡量選擇靠近右邊界的點。然後按照這個排序後的區間進行遍曆,用一個變數來存放遍曆過程中上個區間的右邊界,然後碰到一個新的區間的時候需要分兩種情況討論:1、這個區間和上個區間有相交的部分,那麼就需要判斷一下上次選擇的點有多少在這個區間內,這些點滿足要求嗎?不滿足的話還需要在這個區間內選點2、這個區間和上個區間沒有交集,那麼這個區間就需要選點。
上述策略可以保證右邊界相同的區間,先選擇區間短的那個。因為短區間的點被選擇了,那麼相同右邊界的更大的區間肯定包含這個比較小的區間選擇的所有點,這樣這個大點的區間被滿足的可能性就比較大了。並且這裡選點的策略是取盡量靠近右邊界的點,這樣選取被滿足區間個數會是最大的。
虛擬碼
interval[maxn][2]; sort(interval, interval + maxn, cmp);//cmp按照r小l大優先順序高來排列 pre = interval[1][0] - 1; //製造出不相交的右邊界 for in range(1, maxn): if interval[i][0] > pre://不相交 //靠近右邊界選點 else: //先尋找這個區間已經被選中了多少點,然後根據是否滿足要求再進行選點 pre = interval[1][1]; //更新右邊界 else:;
題目:uva10148Advertisement(區間選點)
區間覆蓋問題(選擇最少的區間使得覆蓋[m,n])
假設覆蓋的區間是[m, n].先預先處理掉和[m,n]不沾邊的區間。把起點小的區間放前面,如果起點相同的區間就把長的區間放前面。做兩個特判,判斷起點最先的區間是否涵蓋m,和最後的覆蓋是否有覆蓋到n。接著就是中間的判斷了,中間的判斷看代碼吧。
虛擬碼
interval[maxn][2]; vis[maxn];//記錄哪條邊被選擇 //刪除和[m, n]不沾邊的區間,並且按照l小r大優先順序高排序 function Cover_Interval: if interval[0][0] < m //是否涵蓋m return false; pre = m;//前一個選擇區間的右邊界,也是下個要選擇區間的有效起始邊界 t = -1;//記錄前一個區間的下標,因為可能這個區間並不是最好的區間 cover = m - 1;//目前已經覆蓋了的位置 for in range(1, maxn): if interval[i][0] <= pre: //滿足至少覆蓋到上個區間右邊界pre,使得整個覆蓋的區間不會斷開 if interval[i][1] > cover: //選取最長的滿足上面的要求的區間 vis[i] = 1; cover = interval[i][1]; //更新覆蓋位置 if t != -1: //上次選中的取消 vis[t] = 0; else: //不滿足要求說明需要選擇下個新的區間,更新pre pre = cover; if interval[i][0] > pre: //如果當前這個區間的左邊界比覆蓋位置更大,那麼說明中間有一段是覆蓋不到的 return false; t = -1; //新的區間清空上次選中 i--; if cover >= n: break; else:; if cover < n return false; //輸出被選擇的區間according to vis[maxn] return true; function end;
題目:uva10020 - Minimal coverage(區間覆蓋)uva10382 - Watering Grass(區間覆蓋變形)
黃金分割法縮小區間時的選點原則是什
黃金分割法縮小區間時的選點原則是什嗎?為何要這樣選點?
選點原則是插入點應按0.618分割區間。
因為這樣選點可以保持兩次迭代區間的相同比例分布,具有相同的縮短率。
黃金分割法縮小區間時的選點原則是什
根據公式a1=b-λ(b-a);a2=a+λ(b-a)
λ=0.618;a,b是剛開始給定的搜尋區間[a,b]。