一、定义

什么是贪心算法呢?所谓贪心算法是指,在对问题求解时,总是做出在当前看来最好的选择。也就是说,不从整体最优解出发来考虑,它所做出的仅是在某种意义上的局部最优解。

贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题都能产生整体最优解或整体最优解的近似解。

贪心算法的基本思路如下:

1.建立数学模型来描述问题。

2.把求解的问题分成若干个子问题。

3.对每个子问题求解,得到每个子问题的局部最优解。

4.把每个子问题的局部最优解合成为原来问题的一个解。

实现该算法的过程:

从问题的某一初始状态出发;

while 能朝给定总目标前进一步 do

求出可行解的一个解元素;

由所有解元素组合成问题的一个可行解;

二、例题分析

[背包问题]有一个背包,背包容量是M=150。有7个物品,物品可以分割成任意大小。

要求尽可能让装入背包中的物品总价值最大,但不能超过总容量。

物品 A B C D E F G

重量 35 30 60 50 40 10 25

价值 10 40 30 50 35 40 30

记得当时学算法的时候,就是这个例子,可以说很经典。

分析:

目标函数: ∑pi最大

约束条件是装入的物品总重量不超过背包容量,即∑wi<=M( M=150)

(1)根据贪心的策略,每次挑选价值最大的物品装入背包,得到的结果是否最优?

(2)每次挑选所占重量最小的物品装入是否能得到最优解?

(3)每次选取单位重量价值最大的物品,成为解本题的策略?

贪心算法是很常见的算法之一,这是由于它简单易行,构造贪心策略简单。但是,它需要证明后才能真正运用到题目的算法中。一般来说,贪心算法的证明围绕着整个问题的最优解一定由在贪心策略中存在的子问题的最优解得来的。

对于本例题中的3种贪心策略,都无法成立,即无法被证明,解释如下:

(1)贪心策略:选取价值最大者。反例:

W=30

物品:A B C

重量:28 12 12

价值:30 20 20

根据策略,首先选取物品A,接下来就无法再选取了,可是,选取B、C则更好。

(2)贪心策略:选取重量最小。它的反例与第一种策略的反例差不多。

(3)贪心策略:选取单位重量价值最大的物品。反例:

W=30

物品:A B C

重量:28 20 10

价值:28 20 10

根据策略,三种物品单位重量价值一样,程序无法依据现有策略作出判断,如果选择A,则答案错误。

值得注意的是,贪心算法并不是完全不可以使用,贪心策略一旦经过证明成立后,它就是一种高效的算法。比如,求最小生成树的Prim算法和Kruskal算法都是漂亮的贪心算法。

[均分纸牌]有N堆纸牌,编号分别为1,2,…,n。每堆上有若干张,但纸牌总数必为n的倍数.可以在任一堆上取若干张纸牌,然后移动。移牌的规则为:在编号为1上取的纸牌,只能移到编号为2的堆上;在编号为n的堆上取的纸牌,只能移到编号为n-1的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。例如:n=4,4堆纸牌分别为:① 9 ② 8 ③ 17 ④ 6 移动三次可以达到目的:从③取4张牌放到④ 再从③区3张放到②然后从②去1张放到①。

输入输出样例:4

9 8 17 6

屏幕显示:3

算法分析:设a[i]为第I堆纸牌的张数(0<=I<=n),v为均分后每堆纸牌的张数,s为最小移动次数。

我们用贪心算法,按照从左到右的顺序移动纸牌。如第I堆的纸牌数不等于平均值,则移动一次(即s加1),分两种情况移动:

1.若a[i]>v,则将a[i]-v张从第I堆移动到第I+1堆;

2.若a[i]

为了设计的方便,我们把这两种情况统一看作是将a[i]-v从第I堆移动到第I+1堆,移动后有a[i]=v; a[I+1]=a[I+1]+a[i]-v.

在从第I+1堆取出纸牌补充第I堆的过程中可能回出现第I+1堆的纸牌小于零的情况。

如n=3,三堆指派数为1 2 27 ,这时v=10,为了使第一堆为10,要从第二堆移9张到第一堆,而第二堆只有2张可以移,这是不是意味着刚才使用贪心法是错误的呢?

我们继续按规则分析移牌过程,从第二堆移出9张到第一堆后,第一堆有10张,第二堆剩下-7张,在从第三堆移动17张到第二堆,刚好三堆纸牌都是10,最后结果是对的,我们在移动过程中,只是改变了移动的顺序,而移动次数不便,因此此题使用贪心法可行的。

Java源程序:

public class Greedy {

public static void main(String[] args) {

int n = 0, avg =0, s = 0;

Scanner scanner = new Scanner(System.in);

ArrayList array = new ArrayList();

System.out.println("Please input the number of heaps:");

n = scanner.nextInt();

System.out.println("Please input heap number:");

for (int i = 0; i < n; i++) {

array.add(scanner.nextInt());

}

for(int i = 0; i < array.size(); i ++){

avg += array.get(i);

}

avg = avg/array.size();

System.out.println(array.size());

System.out.println(avg);

for(int i = 0; i < array.size()-1; i ++){

s++;

array.set(i+1, array.get(i+1)+array.get(i)-avg); }

System.out.println("s:" + s);

}

}

利用贪心算法解题,需要解决两个问题:

一是问题是否适合用贪心法求解。我们看一个找币的例子,如果一个货币系统有三种币值,面值分别为一角、五分和一分,求最小找币数时,可以用贪心法求解;如果将这三种币值改为一角一分、五分和一分,就不能使用贪心法求解。用贪心法解题很方便,但它的适用范围很小,判断一个问题是否适合用贪心法求解,目前还没有一个通用的方法,在信息学竞赛中,需要凭个人的经验来判断。

二是确定了可以用贪心算法之后,如何选择一个贪心标准,才能保证得到问题的最优解。在选择贪心标准时,我们要对所选的贪心标准进行验证才能使用,不要被表面上看似正确的贪心标准所迷惑,如下面的例子。

[最大整数]设有n个正整数,将它们连接成一排,组成一个最大的多位整数。

例如:n=3时,3个整数13,312,343,连成的最大整数为34331213。

又如:n=4时,4个整数7,13,4,246,连成的最大整数为7424613。

输入:n

N个数

输出:连成的多位数

算法分析:此题很容易想到使用贪心法,在考试时有很多同学把整数按从大到小的顺序连接起来,测试题目的例子也都符合,但最后测试的结果却不全对。按这种标准,我们很容易找到反例:12,121应该组成12121而非12112,那么是不是相互包含的时候就从小到大呢?也不一定,如12,123就是12312而非12123,这种情况就有很多种了。是不是此题不能用贪心法呢?

其实此题可以用贪心法来求解,只是刚才的标准不对,正确的标准是:先把整数转换成字符串,然后在比较a+b和b+a,如果a+b>=b+a,就把a排在b的前面,反之则把a排在b的后面。

java源程序:

public static void main(String[] args){

String str = "";

ArrayList array = new ArrayList();

Scanner in = new Scanner(System.in);

System.out.println("Please input the number of data:");

int n = in.nextInt();

System.out.println("Please input the data:");

while (n-- > 0) {

array.add(in.next()); }

for(int i = 0; i < array.size(); i ++)

for(int j = i + 1; j < array.size(); j ++){

if((array.get(i) + array.get(j)).compareTo(array.get(j) + array.get(i)) < 0){

String temp = array.get(i);

array.set(i, array.get(j));

array.set(j, temp);

}

} for(int i = 0; i < array.size(); i ++){

str += array.get(i);

}

System.out.println("str=:"+str); }

}

贪心算法所作的选择可以依赖于以往所作过的选择,但决不依赖于将来的选择,也不依赖于子问题的解,因此贪心算法与其他算法相比具有一定的速度优势。如果一个问题可以同时用几种方法解决,贪心算法应该是最好的选择之一。

python贪心算法几个经典例子_贪心算法及几个经典例子相关推荐

  1. python算法的缺陷和不足_机器学习算法优缺点及其应用领域

    决策树 一.  决策树优点 1.决策树易于理解和解释,可以可视化分析,容易提取出规则. 2.可以同时处理标称型和数值型数据. 3.测试数据集时,运行速度比较快. 4.决策树可以很好的扩展到大型数据库中 ...

  2. python算法工程师需要学什么_人工智能算法工程师与Python工程师有什么区别?

    原标题:人工智能算法工程师与Python工程师有什么区别? 学习Python就等于学习人工智能吗?当然不!千万不要混淆它们的概念!Python工程师并不等同于人工智能工程师. Python工程师与人工 ...

  3. python贪心算法求删数问题_贪心算法删数问题

    删数问题 给定n位正整数a,去掉其中任意k个数字后,剩下的数字按原次序排列组成一个新的正整数.对于给定的n和k,设计一个算法,找出剩下数字组成的新数最少的删数方案. 输入示例: 178543 4 输出 ...

  4. python判断两个数是否互质_《算法》第一章——判断两个整数是否互质

    判断两个整数互质的方法 概念:公约数只有1的两个数叫做互质数.根据互质数的概念可以对一组数是否互质进行判断.如:9和11的公约数只有1,则它们是互质数. 求商判断法:用大数除以小数,如果除得的余数与其 ...

  5. Java斗地主算法的设计与实现_斗地主算法的设计与实现–洗牌和发牌

    本篇将给出斗地主算法的源码,介绍斗地主这个项目的一些基本情况. 下载地址:http://download.csdn.net/detail/fansunion/6387589 特别说明:斗地主项目的主要 ...

  6. 堆排序算法讲解视频java版_堆排序算法的讲解及Java版实现

    堆是数据结构中的一种重要结构,了解了"堆"的概念和操作,可以快速掌握堆排序. 堆的概念堆是一种特殊的完全二叉树(complete binary tree).如果一棵完全二叉树的所有 ...

  7. 堆排序算法java左程云_堆排序算法以及JAVA实现

    堆的定义如下: n个元素的序列{k0,k1,...,ki,-,k(n-1)}当且仅当满足下关系时,称之为堆. " ki<=k2i,ki<=k2i+1;或ki>=k2i,ki ...

  8. java 序列化 例子_一个简单的Java序列化的例子

    简单来说序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化,流的概念这里不用多说(就是I/O),我们可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间(注:要想将对 ...

  9. 计算机思维与算法设计论文,计算思维_计算机算法的表示和设计.pptx

    计算思维;1.一般问题处理过程与计算机处理问题过程区别2.算法的表示3.变量及其赋值4.顺序结构算法5.选择结构/分支结构6.循环结构7.简单算法;一般问题处理过程与计算机处理问题过程有何不同呢?;1 ...

  10. 概率论在实际生活的例子_概率论中几个有趣的例子

    转载]概率论中几个有趣的例子 [ 2007-6-3 13:06:00 | By: Byron ] 推荐 作者: ni1985 (妮子||从东方席地卷来一团野火), 原发新水木Mathematics 已 ...

最新文章

  1. 基于全景图像与激光点云配准的彩色点云生成算法(2014年文章)
  2. weblogic 启动项目失败,JMS 队列通过http 方式访问
  3. 找出不超过40亿个给定整数的整数
  4. java 定义类变量初始化吗_Java的变量有哪些类型?变量如何定义?如何初始化?请说明理由并举例_学小易找答案...
  5. 数据结构特性解析 (一) 数组
  6. struts练习-表单提交
  7. MSP432P401R TI Drivers 库函数学习笔记(二)认识TI-RTOS (TI-POSIX)
  8. BZOJ 3304: [Shoi2005]带限制的最长公共子序列( LCS )
  9. 铁甲雄兵显示服务器维护,《铁甲雄兵》5月17日09:00停机维护公告
  10. java中.length得到结果_Java length()方法:获取字符串的长度
  11. Palindrome Number
  12. asp.net+mysql,asp.net+mysql后台盲注入
  13. 【Android取证篇】三星手机开启开发者模式
  14. 利用python计算n阶行列式的源代码
  15. setBackground()和setImageBitmap()看完就哦了
  16. Jetson Nano系列教程3-生死看淡,不服就干之GPIO
  17. 低成本无线门铃芯片_无线门铃ic选型分析
  18. 微信小程序功能:商品收藏-图片预览-客服-分享-加入购物车
  19. 国产软件不背黑锅,4款强大又实用的电脑软件,用了舍不得卸载
  20. 水星m313 v5 的DMZ主机问题

热门文章

  1. cc2530设计性实验代码六
  2. android adb sdk下载地址,Android SDK 下载和安装
  3. 中文核心期刊目录(2008年最新版)
  4. 贪吃蛇游戏设计预习01
  5. 2022年最新《谷粒学院开发教程》:6 - 整合SpringCloud
  6. c++整人小程序无限弹窗(附源码)
  7. 软考-网络工程师复习资料
  8. CSDN获得c币办法
  9. 数据结构(C语言版)严蔚敏李冬梅(第2版)课后习题答案
  10. mac使用Java命令运行Java程序