贪心算法Q2——零钱兑换
/*问题描述
- 假设有25分、10分、5分、1分的硬币,
- 先要发给客户41分的零钱,如何办到硬币个数最少?
*/
package 贪心;
import java.util.Arrays;
//用贪心策略求得的不一定是全局最优解
//此题若换成 25 20 5 1四种面值 按照该算法结果应为 面值25 5 5 5 1一共需要5张
//显然不对 正确结果应该为20 20 1只需要3张即可
//因为没有遍历全部可能性解 只是当前这一步可以达到的局部最优解 过早做出决定
//贪图眼前局部利益的最大化 没有放眼长远未来 走一步看一步
//通常作为辅助策略来使用
public class 零钱兑换 {
static void moneyChange(Integer[] a,int money) {
Arrays.sort(a,(Integer a1,Integer a2)->{return a2-a1;});
//25 10 5 1 41
int i=0;
while(i<a.length) {
if(money<a[i]) {//当剩余的钱小于该面值时 i++跳过该面值
i++;
continue;
}
//能执行到这里说明当前剩余的前大于该面值却比上一次面值小 该面值为当前最适
money-=a[i];
System.out.println(a[i]);
}
}
static void moneyChange2(Integer[] a,int money) {
//从小往大排:1 5 10 25
Arrays.sort(a);
int count=0;
for(int i=a.length-1;i>=0;i--) {
if(money<a[i]) {//当所有面值都比剩余的钱大时 结束循环
continue;
}
money-=a[i];
System.out.println(a[i]);
count++;
//选了最大面值之后 还要从最大开开始重新枚举
i=a.length;
}
System.out.println(count);
}
public static void main(String[] args) {
Integer[] faces= {5,10,25,1};
//或者Arrays.sort(faces,(Integer a1,Integer a2)-> a2-a1);
int money=41;
//moneyChange(faces,money);
moneyChange2(faces,money);
}
}