贪心算法(Greedy algorithm),又称贪婪算法。是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而使得问题得到全局最优解。
贪心的算法的设计就是要遵循某种规则,不断地选取当前最优解的算法设计方法。这节实验将会通过多个问题的来讲解贪心算法。
贪心算法基本概念
贪心算法与枚举法的不同之处在于每个子问题都选择最优的情况,然后向下继续进行,且不能回溯,枚举法是将所有情况都考虑然后选出最优的情况。
贪心算法,在对问题求解时,不从整体考虑,而是采用一叶障目的选择方式,只选择某种意义上的局部最优解。并且,贪心算法是没有固定的模板可以遵循的,每个题目都有不同的贪心策略,所以算法设计的关键就是贪心策略的选择。
贪心算法有一个必须要注意的事情。贪心算法对于问题的要求是,所有的选择必须是无后效性的,即当前的选择,不能影响后续选择对于结果的影响。
适用范围
符合贪心策略:
所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。
所谓的贪心选择性质就是,该问题的每一步选择都在选择最优的情况下能够导致最终问题的答案也是最优。
或者说是无后效性,如果该问题的每一步选择都对后续的选择没有影响,就可以是应用贪心算法。
贪心算法的设计步骤
按照定义设计:
-
证明原问题的最优解之一可以由贪心选择得到。
-
将最优化问题转化为这样一个问题,即先做出选择,再解决剩下的一个子问题。
-
对每一子问题一一求解,得到子问题的局部最优解;
-
把子问题的解局部最优解合成原来解问题的一个解
实战演练
找零钱问题
题目描述
蓝桥商店的老板需要找零 n元钱。
钱币的面额有:100 元、50 元、20 元、5 元、1元,问如何找零使得所需钱币的数量最少?
注意:n可能为 0,也能为几百元
输入描述
在第一行给出测试例个数 NN,代表需要找零的钱数。
输出描述
输出共有 5 行,每一行输出数据输出找零的金额与数量,详情看样例。
示例
输入
365
输出
100:3
50:1
20:0
5:3
1:0
代码实现:
package easy;
import ;
public class 找零问题贪心 {
static int[] arr = {100,50,20,5,1}; //用来存纸币面额
static int[] num = new int[5]; //每种纸币的数量
public static void main(String[] args) {
Scanner sc = new Scanner();
int n = ();
f(n);
for (int i = 0; i < ; i++) {
(arr[i]+":"+num[i]);
}
}
static void f(int n) {
//遍历arr数组
for (int i = 0; i < ; i++) {
// 求出每类纸币需要多少张
num[i] = n / arr[i];
n = n % arr[i];
}
}
}