一、定义

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

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

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

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 classGreedy {public static voidmain(String[] args) {int n = 0, avg =0, s = 0;

Scanner scanner= newScanner(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的后面。

个人理解:整数转字符串a+b = '12'+'123'='12123'

java源程序:

public static voidmain(String[] args){

String str= "";

ArrayList array = new ArrayList();

Scanner in= newScanner(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. 结构化分析和面向对象分析的区别 例子_管理游戏测评例子

    在测评中心技术中,有一个非常有趣的场景的模拟测评,打造敏捷高绩效团队,提高执行力(包括人才测评),旨在帮助学生培养自主性,了解自己,以独立的意见做出决策,采取果断的行动:培养赋权型领导:树立分享意识, ...

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

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

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

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

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

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

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

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

  10. mysql 经典面试_这些MySQL经典面试题你要知道!

    1.MySQL的复制原理以及流程(1).复制基本原理流程 1. 主:binlog线程--记录下所有改变了数据库数据的语句,放进master上的binlog中: 2. 从:io线程--在使用start ...

最新文章

  1. Linux RPM 初步学习
  2. 概率统计笔记: 卡方分布(介绍)
  3. PHP中empty,is_null,isset的区别
  4. Shoutem旨在成为React Native移动应用领域的WordPress
  5. linux14.10硬盘安装,Windows 10下硬盘安装Ubuntu 14.10图文教程
  6. 【registries】registrie rest-service idea 无法引入
  7. vue ui没反应如何解决?
  8. 【Java每日一题】20161124
  9. (其他)用sublime text3编写的html网页用浏览器打开出现中文乱码的原理及解决方法(转)...
  10. 安卓商城 php后台,洛克商城APP 开源商城安卓源码 含前端和后台
  11. solr自定义分词器
  12. 干货!手把手教你搭建高可用架构
  13. 华硕笔记本怎么禁用自带键盘
  14. 【知乎答案】2018校招,笔试应该怎么准备?|牛客网回答
  15. Linux---Apache网页优化---网页压缩
  16. 特征工程7种常用方法
  17. (十四)懈寄生(4)
  18. 假如生活欺骗了你……
  19. 小米4A刷入breed教程
  20. STN32单片机学习笔记(五)-按键检测

热门文章

  1. MySQL5.7安装包安装
  2. JAVA计算机毕业设计幼儿园管理系统Mybatis+系统+数据库+调试部署
  3. java异常处理拦截器
  4. 莫烦pytorch学习笔记(三)
  5. AMPL—快速了解,秒懂它。
  6. java比python快多少倍_java为什么比python快
  7. uu云验证码识别平台,验证码,验证码识别,全自动验证码识别技术,优优云全自动打码,代答题系统,优优云远程打码平台,uu云打码...
  8. 软件项目管理 project 实验
  9. 显示器、显卡的接口类型
  10. 山东计算机平面设计学校,什么人适合学平面设计?山东有哪些开设平面设计的学校?...