一、什么是贪心策略呢?
贪心算法是一种递推算法,用局部最优解来推导全局最优解,是对遍历解空间的一种优化
当问题具有最优子结构时,可用动态规划,而贪心是动态规划的一种特例
- 特点:
只看眼前
遵循某种规则,不断(贪心)选取当前最优策略,最终找到最优解。
难点:当前最优解未必是整体最优。
- 二、题目:硬币问题
有1元,5元,10元,50元,100元,500元的硬币各c1,c5,c10,c50,c100,c500枚,现在要用这些硬币来支付A元,最少需要多少枚硬币?
假定本题至少存在一种支付方案
0<=ci<=10^9
0<=A<=10^9
输入:
第一行有6个数字,分别代表从小到大6中面值的硬币个数
第二行为A,代表需要支付的A元。
样例:
输入:
3 2 1 3 0 2
620
输出
6
分析思路:
要求用最少的硬币数量来解决问题
从一般角度思考,首先使用最大的面额500元一张,100元一张,10元2张。
但是,在样例中并没有100元的,所以仍然是500元一张,50元2张,10元2张
上面有很多种可以选择的路,找到最优的,一直按这种最优的走下去。例如:第一张就选择500的,之后再找剩下的最优的
- 代码
package cointanxin;
import java.util.Scanner;
public class Cion {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
for(int i=0;i<6;i++) {
cnts[i]=sc.nextInt();
}
int A=sc.nextInt();
int res=f(A,5);//当前面值最大的硬币,下标为5
System.out.println(res);
}
static int[] cnts=new int[6]; //一开始就选择下标为最大的500
static int[] coins= {1,5,10,50,100,500};
//尽量选取最大面值,若不选取最大面值,将使用更多小面值的硬币,一定得不到最优解
static int f(int A,int cur) {
if(A<=0)
return 0;
if(cur==0)
return 0;
int coinValue=coins[cur];
int x=A/coinValue; //当前面值的硬币有cnt个
int cnt=cnts[cur]; //当前面的硬币有cnt个
int t=min(x,cnt);
return t+f(A-t*coinValue,cur-1); //用t个当前面值,剩下的继续处理
}
}