目录
概念
什么是贪心算法?就是对问题求解的时候,能够做出当前(关键是当前)看起来最好的选择,也就是它强调的是局部最优解
所以说,对于整个问题来说不一定能够就是求得最优解,需要看问题
什么时候选择贪心算法:问题必须具备无后效性,也就是某个状态在以后的过程中不会影响之前的状态,只与当前状态有关
关键:贪心算法只需考虑一个选择(亦即,贪心的选择);在做贪心选择时,子问题之一必须是空的,因此只留下一个非空子问题
心算法通常是自顶向下地做出贪心选择,不断地将给定的问题实例归约为更小的问题。贪心算法划分子问题的结果,通常是仅存在一个非空的子问题
基本思路
1.把问题分为多个子问题——>2.然后对每个问题都求解得到子问题的局部最优解——>3.把子问题最优解进行合并判断得到最后问题解
例题:钱币找零
假设纸币金额为1元、5元、10元、20元、50元、100元,要求我们找零兑的钱纸最少,123元应该尽可能兑换少的纸币。
按尝试应该兑换1张100、1张20元和3张1元的。
思想:每一步尽可能用面值大的纸币——>1.遍历每一种面额情况100,50...——>2.然后循环每种面额的能够换几次
/**
* 零钱兑换
* @param money
*/
static void splitChange(int money) {
int[]prices={100,50,20,10,5,1};
int[]notes=new int[prices.length];//记录每种面额使用张数
int change=money;
if(money>0){
while(change>0){
//面额的选择
for (int i = 0; i < prices.length; i++) {
//记录面额的使用数
int count=0;
//看这种面额的能循环找出几张
for (int k = 0; change- prices[i]>=0 ; k++) {
if(change-prices[i]>=0){
change=change-prices[i];
count++;
}else{
break;
}
}
notes[i]=count;
}
}
}
System.out.println("找零:");
for (int num = 0; num < prices.length; num++) {
System.out.print(notes[num] + "张" + prices[num] + "元 ");
}
}
课程安排
思路:1.按照时间对课程进行排序——>2.然后遍历课程进行筛选,如果时间比截至日期短则进行添加——>3.如果遍历课程发现超过时间了,则对之前已经筛选过的课程进行遍历然后将耗时较长的进行替换,然后更新时间
/**
* 课程安排
* 思路:1.给定一个数组courses ,对其进行排序并维护当前日期——>2.可以选择课程,那么增加当前日期
* ——>3.如果不可选,选择已经选过耗时最长的课程比较当前课程哪个时间长,长的不要——>保证了指定时间范围内能够选择的最多课程
* 它的每一个元素courses表示两门课程之间的先修顺序。
* 例如courses[i] = [ai, bi]表示想要学习课程 ai,需要先完成课程 bi
*
* @param courses:课程对应时长,以及截止日期
* @return
*/
public int scheduleCourse(int[][] courses) {
//1.排序
Arrays.sort(courses, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[1] - o2[1];
}
});
int count = 0, curtime = 0;
for (int i = 0; i < courses.length; i++) {
/**
* 2.遍历每个课程的时间,若可选(<截止日期),增加当前时间,并且将当前课程放入courses
*/
if (curtime + courses[i][0] <= courses[i][1]) {
courses[count++] = courses[i];
curtime += courses[i][0];
} else {
int max_i = i;
/**
* 3.遍历已经选的课程count,将耗时较长的替换
*/
for (int j = count - 1; j >= 0; j--) {
//3.1找到已选课程中耗时较长的课程
if (courses[j][0] > courses[i][0]) max_i = j;
}
//3.2更新课程,并且更新最大时间
if (courses[max_i][0] > courses[i][0]) {
curtime += courses[i][0] - courses[max_i][0];
courses[max_i] = courses[i];
}
}
}
return count;
}
public class greedyProgramTest {
public static void main(String[] args) {
//找零问题
int money = 123;
greedyProgram.splitChange(money);
System.out.println();
System.out.println("-------");
//多机调度问题
int[] a = {5,4,2,14,16,6,5,3};
int m = 3;
System.out.println("总时间为:"+greedyProgram.greedy(a,m));
System.out.println("-------");
//课程表
int[][] course = {{2,5},{2,19},{1,8},{1,3}};
System.out.println(Solution.scheduleCourse(course));
}
}