算法起步之贪心算法

原文:算法起步之贪心算法

       我们前面介绍的动态规划算法是求解最优化问题的一种通用方法,但是对于很多的最优化问题是用动态规划有点小题大做了,我们可以使用贪心算法,贪心算法相比动态规划更简单,也更高效。它总是做出局部最优选择,希望这样可以得到全局的最有选择。所以这种方法不能保证得到最优解,但是很多问题却都可以用这种方法。我们先看一个活动选择的例子。

       假设我们有n个活动,只有一个教室,求在这个教室中一天最多可以举办多少活动(同一时间只能举办一个活动)。下面给出的是活动的开始时间跟结束时间。

i序号 1 2 3 4 5 6 7 8 9 10 11
s开始 1 3 0 5 3 5 6 8 8 2 12
f结束 4 5 6 7 9 9 10 11 12 14 16

       动态规划解法:

       本来想这个用动态规划很简单,看了一下算法导论写的,只写了一个递归的算法,但是递归的效率太低,于是就想写自底向上的,写了一个简单的确发现自己想错了,于是在网上找了很多动态规划解活动选择的问题,都不太满意,都不是按照我想的那样,很多写的算法时间复杂度达到了n的三次方。今天又看了一遍题目,突然写了出来,虽然耽误了很多时间,但是我觉得这比网上其他给的答案还要快一点。

public class DPActity {
	public void actity(){
		Scanner sc=new Scanner(System.in);
		int[][] map=new int[25][25];
		for (int i = 0; i < 11; i++) {
			map[sc.nextInt()][sc.nextInt()]=1;
		}

		for(int i=1;i<map.length;i++){
			for(int j=0;j<=i;j++){
				if(map[j][i]==1){
					map[0][i]=max(map[0][i-1], 1+map[0][j]);
				}else{
					map[0][i]=max(map[0][i-1],map[0][i]);
				}
			}
		}
		System.out.println(map[0][24]);
	}
	public int max(int a,int b){
		if(a>b){
			return a;
		}else{
			return b;
		}
	}

	public static void main(String[] args) {
		new DPActity().actity();
	}

}

          虽然这样写的感觉代码也不多,但是如果我们用贪心的做法你会发现非常简单,而且好理解。因为我们的数值倒是按照结束时间排序的,所以一直选择结束时间最短的则获得最优解。在这里选择结束时间最早的活动就是我们的决策点。而贪心算法关键就是在选择决策点上。顺便一提像01背包问题不能用贪心算法来解但是分数背包可以解决。

public void greedy(int[]s,int[]f){
		int n=s.length;
		int k=1;
		for (int i = 2; i < n; i++) {
			if (s[i]>=f[k]) {
				k=i;
			}
		}
		System.out.println(k);
	}

友情提示:转载请注明出处【作者:idlear  博客:http://blog.csdn.net/idlear

时间: 2024-08-17 18:35:09

算法起步之贪心算法的相关文章

算法起步之Bellman-Ford算法

原文:算法起步之Bellman-Ford算法            从这篇开始我们开始介绍单源最短路径算法,他是图算法之一,我们前面说的贪心,图的遍历,动态规划都是他的基础,单源最短路径其实说的就是图中节点到节点的最短路径.就像我们使用百度地图从哪到哪一样,找出最近的距离,而单源最短路径问题不只是两点之间的路径,他有很多的变形,像单目的地最短路径问题,单节点对最短路径问题,所有节点对最短路径问题,最短路径的最优子结构问题.         在介绍这类算法之前我们先规定节点的基本属性,我们规定节点

算法起步之Prim算法

原文:算法起步之Prim算法            prim算法是另一种最小生成树算法.他的安全边选择策略跟kruskal略微不同,这点我们可以通过一张图先来了解一下.            prim算法的安全边是从与当前生成树相连接的边中选择一条最短的一条,并且该边是应是生成树与生成树外一点的连接.            所以我们prim算法用汉字描述的过程应为:1初始化2构造最小优先队列,将所有节点都加入到最小优先队列中,所有节点的key设置为无穷大,开始节点设置成0.3循环,直到队列为空{

算法起步之选择算法

原文:算法起步之选择算法           什么是选择算法,其实很简单,从一堆数里选择最大值或最小值就是选择算法.这样一说大家是不是觉得太简单了,其实选择算法,选择并不只是选择最大或是最小,相信这样的算法大家都能写的出来,一趟遍历就可以得到,但是选择算法是找出第几小或者是第几大的数,这样是不是没有刚才说的那么简单了呢.但是他们期望的时间复杂度却都是相同的都是O(n),简单的说就是希望一趟遍历就可以得到第几小第几大的数,其实选择算法跟上一篇我们说的额快排在实现上是有很多相似的地方的. publi

【算法导论】贪心算法之背包问题

        在讨论贪心算法时,我们先了解贪心算法与动态规划之间的区别与联系,后面我们将发现可以用0.1背包问题和部分背包问题来比较贪心算法和动态规划的关系.         我们知道,对于一个最优解问题,贪心算法不一定能够产生一个最优解.因为,如果想要采用贪心算法得到最优解需要满足两个条件:贪心选择性质.最优子结构.         贪心选择性质:一个全局最优解可以通过局部最优解来得到.that is to say,当考虑如何做选择时,我们只考虑对当前问题最佳的选择而不考虑子问题的结果.  

【算法导论】贪心算法之活动安排问题

         对于许多最优化问题来说,采用动态规划来求解最优解有点大材小用了,只需要采用更简单有效的贪心算法就行了.贪心算法就是所做的每一步选择都是当前最佳的,通过局部最佳来寻求全局最佳解.就像砝码称重一样,总是优先选择大的砝码.          贪心算法对大多数优化问题来说能产生最优解,但也不一定总是这样的.能用贪心算法解的典型问题包括活动选择问题.最小生成树.最短路径问题等等.下面我们来讨论活动活动选择问题:           对于上面问题,贪心算法的思想就是:贪心选择使得剩下的.未

《算法技术手册》一1.3.1 贪心算法

1.3.1 贪心算法 以下的贪心算法展示了如何找到凸包上的每个点: 1. 删除P中的最低点low--low必须在凸包上. 2. 垂直画一条穿过点low的直线,将剩余的n-1个点分别和点low连线,以垂直直线右侧的点的夹角为正值降序排列,夹角的范围是从90皛-90啊n-2是最右侧的点,而P0是最左侧的点.图1-3中显示了垂直线以及每个点与其的夹角. 3. 以{Pn-2, low, P0}这个顺序组成的点集为基础,在剩余的点中选择可以组成凸包的点--从P1开始,将每个点尝试加至这个点集的尾部,如果

贪心算法的C语言实现与运用详解_C 语言

贪心算法 所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解. 贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解.贪心算法的基本思路如下: 1.建立数学模型来描述问题. 2.把求解的问题分成若干个子问题. 3.对每一子问题求解,得到子问题的局部最优解. 4.把子问题的解局部最优解合成原来解问题的一个解.   实现该算法的过程: 从问题的某一初始解出

五大常用算法——分治法,动态规划,回溯法,分支界限法,贪心算法

分治算法一.基本概念    在计算机科学中,分治法是一种很重要的算法.字面上的解释是"分而治之",就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题--直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并.这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)--     任何一个可以用计算机求解的问题所需的计算时间都与其规模有关.问题的规模越小,越容易直接求解,解题所需的计算时间也越少.例如,对于n个元素

贪心算法的理解与实例应用

问题描述 贪心算法的理解与实例应用 对贪心算法的深刻理解,以及贪心算法的经典应用,对相应的实例进行分析 解决方案 哈夫曼树-贪心算法的应用实例strtotime 深入理解应用实例---------------------- 解决方案二: 可参考 http://blog.csdn.net/effective_coder/article/details/8736718