贪心算法典型应用,以及函数技巧使用

贪心:定义 • 本质:每步只选择当前最优解 • 局部最优=全局最优解?

• 这是非常强的性质 • 总的来说: • 想到容易(不记录历史状态,符合人类直觉)

• 证明困难(反证法,矩阵胚)

• 应用广泛(求较优解)

接下来直接上题目,已练代理解

贪心:

例题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() {
			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;iarr[i-count][1]){
					sum++;
				}
			}
		}
		System.out.println(sum);
	}
}

 

深刻理解:

核心思想去冗余,比如这道题,要求安排的任务数最多,所以出现时间重叠时,从头开始想,如果第一和第二个元素就重合,则需要去除结束时间晚的,为后面剩下时间长度。思维方式就是从源头开始想,最开始的那个元素开始,当然是建立在排好序的情况下。

你可能感兴趣的:(算法手撕代码)