1. 程式人生 > >貪心算法----區間覆蓋問題(POJ2376)

貪心算法----區間覆蓋問題(POJ2376)

println 選擇 -- scan 第一個 mat return java this

題目:

  技術分享圖片

  題目的大概意思是約翰這個農民有N條牛,這些牛可以在一天中的某個時間段可以進行工作,他想把這個時間段分成若幹個片段讓這些牛去進行打掃任務,你的任務是安排盡量少的牛然後可以完成分成這些片段的打掃任務。

  輸入:

    第一行兩個數,第一個數代表牛的個數N,第二個數代表時間T,表示的是時間段[1,T]。

    下面的N行每行表示牛工作的時間段。

  輸出:

    輸出使用最少的牛的數量。

  思路分析:這道題目完全就是一個區間覆蓋問題的裸題,求解過程,將每個牛工作的區間按左端點遞增排序,如果左端點相同,按右端點遞增順序排列。設置start變量初始化為時間段的左端點,在這些區間中找到滿足左端點小於start並且右端點盡量往右靠的區間,然後將這個區間的右端點設置為end變量,這樣就找到了一個區間,然後將start變量更新為end變量,然後再在剩下的區間繼續尋找左端點小於start並且右端點盡量往右靠的區間,然後再將這個區間的右端點設置為end變量,這樣就又找到了一個區間,如此循環下去,直到end大於時間段的右端點,退出循環,這樣就能找出使用哪些區間能夠覆蓋這個時間段了。解答這道題目在循環中使用一個變量計數即可。

  貪心思想:要求用最少的區間進行覆蓋,那麽選取的區間必然要盡量長,而已覆蓋到的區域之前的地方已經不用考慮了,可以理解成所有可覆蓋的左端點都已被覆蓋了,那麽能夠使得區間更長的取決於右端點,左端點沒有太大的意義,所以選擇右端點來覆蓋。而且在循環的過程中,相當於很多的子問題最優組成了全局的最優。找到每個能夠使用的最長區間就相當於子問題最優,而每個子問題最優就構成了使用的區間數最少這個全局最優。

  代碼:

 1 import java.util.Arrays;
 2 import java.util.Scanner;
 3 
 4 public class 區間覆蓋問題 {
 5
public static void main(String[] args) { 6 Scanner sc = new Scanner(System.in); 7 int N = sc.nextInt(); 8 int T = sc.nextInt(); 9 Job[] jobs = new Job[N]; 10 for (int i = 0; i < N; i++) { 11 jobs[i] = new Job(sc.nextInt(), sc.nextInt());
12 } 13 Arrays.sort(jobs); 14 int start = 1;// 要覆蓋的目標點,end覆蓋該點的所有區間中右端點最右 15 int end = 1; 16 int ans = 1; 17 for (int i = 0; i < N; i++) { 18 19 int s = jobs[i].s; 20 int t = jobs[i].t; 21 22 if (i == 0 && s > 1) 23 break; 24 25 if (s <= start) {// 當前區間有可能覆蓋start 26 end = Math.max(t, end);// 更新更右的端點 27 } else {// 開始下一個區間 28 ans++;// 上一個目標覆蓋已經達成,計數加1 29 start = end + 1;// 更新起點,設置一個新的覆蓋目標 30 if (s <= start) { 31 end = Math.max(t, end); 32 } else { 33 break; 34 } 35 } 36 if (end >= T) {// 當前的end超越了線段的右側 37 break; 38 } 39 40 } 41 if (end < T) 42 System.out.println(-1); 43 else 44 System.out.println(ans); 45 } 46 47 private static class Job implements Comparable<Job> { 48 int s; 49 int t; 50 51 public Job(int s, int t) { 52 this.s = s; 53 this.t = t; 54 } 55 56 /** 按照區間起點排序 */ 57 @Override 58 public int compareTo(Job other) { 59 int x = this.s - other.s; 60 if (x == 0) 61 return this.t - other.t; 62 else 63 return x; 64 } 65 } 66 }

  結果:

    技術分享圖片

貪心算法----區間覆蓋問題(POJ2376)