貪心:定義 • 本質:每步只選擇當前最優解 • 局部最優=全局最優解?
• 這是非常強的性質 • 總的來說: • 想到容易(不記錄歷史狀態,符合人類直覺)
• 證明困難(反證法,矩陣胚)
• 應用廣泛(求較優解)
接下來直接上題目,已練代理解
貪心:
例題1 • 有若干個活動,第i個開始時間和結束時間是[Si, Ei),活動之 間不能重合,求最多安排多少個任務?
• 貪心策略: 按照開始時間排序,開始時間一樣則按照結束時 間排序,按順序加入任務,如果新加入的任務比上一個任務 結束時間早,則替換
• 簡證:加過的過程使得答案+1,替換的過程使得解佔用的時 間變短,在這種情況下得到的解,無法加入新的活動使得答 案+1,也無法通過替換使得佔用時間變短,所以最優 • 時間複雜度:O(nlogn)
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Come {
//直接重寫比較器,然後加循環的小技巧
public static void main(String[] args) {
Math.round(1.45);
Scanner cin = new Scanner(System.in);
//數組的大小,先自己定義開闢大小,直接copy一份到新的數組
int narr[][] = new int[1000][2];
int a = 0;
while(cin.hasNext()){
//使用異常作爲判斷條件,進行捕獲
try {
narr[a][0] = cin.nextInt();
narr[a][1] = cin.nextInt();
a++;
} catch (Exception e) {
break;
}
}
int[][] arr = Arrays.copyOf(narr, a);
Arrays.sort(arr,new Comparator<int []>() {
public int compare(int[] a, int[] b) {
if(a[0]-b[0] == 0){
return a[1]-b[1];
}
return a[0]-b[0];
}
});
//在思路把握正確時,做了最優的優化,直接輸出
//直接遍歷第二列,取每段的第一個數字,如果大於前一段則加一,否則不變
int sum = 0;
int count =0;
for(int i =0;i<arr.length-1;i++){
if(arr[i][0] == arr[i+1][0]){
count++;
}else{
if(arr[i][1]>arr[i-count][1]){
sum++;
}
}
}
System.out.println(sum);
}
}
深刻理解:
核心思想去冗餘,比如這道題,要求安排的任務數最多,所以出現時間重疊時,從頭開始想,如果第一和第二個元素就重合,則需要去除結束時間晚的,爲後面剩下時間長度。思維方式就是從源頭開始想,最開始的那個元素開始,當然是建立在排好序的情況下。