贪心算法与分治
动态规划和贪心算法都是一种递推算法,均用局部最优解来推导全局最优解,是对遍历解空间的一种优化。
当问题具有最优子结构时,可用动态规划,而贪心是动态规划的特例。
什么是贪心策略?
顾眼前:遵循某种规则,不断(贪心得)选取当前的最优策略,最终找到最优解(言外之意就是,只追求眼前的最优,不考虑长远。)
(举个股票的例子,股票的未来增长趋势并不知道,在当前某个增长点,知道他是增长的,打算买入,不考虑未来变化趋势,这就是一种贪心策略。)
难点:当前最优未必是整体最优。
package 动态规划与贪心算法;
import java.util.Scanner;
/**
* 有1元、5元,10元,50元,100元,500元的硬币各c1,c5,c10,c50,c100,c500枚,现在要用这些硬币来支付A元,最少需要多少枚硬币?
假定本题至少存在一种支付方案,且
0<=ci<=10^9 0<=A<=10^9
输入:
第一行有六个数字,分别代表从小到大6种面值的硬币的个数
第二行为A,代表需支付A元
样例输入:
3 2 1 3 0 2
620
样例输出:
6
* @author 万物甦醒
*
*/
public class 硬币支付问题 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
for(int i = 0; i<6 ; i ++) {
cnts[i] = scanner.nextInt();
}
int A = scanner.nextInt();
int res = f(A,5);
System.out.println(res);
}
static int[] cnts =new int[6];
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 A;
int coinValue = coins[cur];
int x = A/coinValue; //金额有多少个coinValue
int cns = cnts[cur]; //当前面值的硬币值有cnt个
int t =min(x,cns);
return t+f(A-t*coinValue, cur-1);
}
private static int min(int x, int cns) {
// TODO 自动生成的方法存根
return x>=cns? cns:x;
}
}