1. 程式人生 > >貪心演算法-整數區間-JAVA

貪心演算法-整數區間-JAVA

貪心演算法-整數區間

【題目描述】 

我們定義一個整數區間[a,b],a,b是一個從a開始至b 結束的連續整數的集合。編一個程式,對給定的 n個區間,找出滿足下述條件的所含元素個數最少的集合中元素的個數:對於所給定的每一個區間,都至少有兩個不同的整數屬於該集合。(1<=n<=10000,  0<=a<=b<=1000)

輸入輸出格式:

輸入:第一行一個正整數n,接下來有n行,每行給定一個區間的a,b值

輸出:一個正整數,即滿足條件的集合所包含的最少元素個數

輸入輸出樣例

輸入:           輸出:

4                  4

3 6

2 4

0 2

4 7

【演算法分析】

本題資料規模較大,用搜索做會超時,而動態規劃無從下手。考慮貪心演算法。題目意思是要找一個集合,該集合中的數的個數既要少又要和所給定的所有區間有交集。(每個區間至少有兩個該集合中的數)。我們可以從所給的區間中選數,為了選儘量少的數,應該使所選的數和更多的區間有交集這就是貪心的標準。一開始將所有區間按照右端點從小到大排序。從第一個區間開始逐個向後檢查,看所選出的數與所檢視的區間有無交集,有兩個則跳過,只有一個數相交,就從當前區間中選出最大的一個數(即右端點),若無交集,則從當前區間選出兩個數,就(右端點,右端點-1),直至最後一個區間。

import java.util.Scanner;


public class Main {
	//貪心演算法-整數區間
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt();
		int[] a = new int[N];//下限
		int[] b = new int[N];//上限
		int[] n = new int[1000];
		int output = 0;
		for (int i = 0; i < N ; i++) {
			a[i] = sc.nextInt();
			b[i] = sc.nextInt();
		}
		//按上限的大小,從小到大排序。
		for (int i = 0; i < N; i++) {
			for (int j = i+1; j < N; j++) {
				if(b[j]<b[i]){
					int temp = b[j];
					b[j] = b[i];
					b[i] = temp;
					temp = a[j];
					a[j] = a[i];
					a[i] = temp;
				}
			}
		}
		//從區間中取數,標記在n[]陣列中。
		for (int i = 0; i < N; i++) {
			int flag = 0;//用於表示該區間內已經取了多少個數。
			for (int j = a[i]; j < b[i]+1; j++) {
				flag += n[j];
			}
			switch (flag) {
			case 0:
				n[b[i]-1] = 1;
				n[b[i]] = 1;
				break;
			case 1:
				n[b[i]] = 1;
				break;
			default:
				break;
			}
		}
		for (int i = 0; i < n.length; i++) {
			output += n[i];
		}
		System.out.println(output);
	}
}