动态规划——硬币找零问题(java)

如果要求一个问题的最优解(通常是最大值或者最小值),而且该问题能够分解成若干个子问题,并且小问题之间也存在重叠的子问题,则考虑采用动态规划。

使用动态规划特征: 
1.
求一个问题的最优解 
2.
大问题可以分解为子问题,子问题还有重叠的更小的子问题 ,即整体问题最优解取决于子问题的最优解(状态转移方程) 
3.
从上往下分析问题,从下往上解决问题 
4.
讨论底层的边界问题

例1:硬币问题

我们有面值为135元的硬币各无数枚,如何用最少的硬币凑够21(这个值可以随意指定)元? 

分析: 
1.
求问题的最优解:最小的硬币数 
2.
是否有子问题:假设f(n)表示凑够n元的最少硬币数。则显然,f(n)=min(f(n-1),f(n-3),f(n-5)) + 1;
3.
确定最小问题的解。 
f(1)=1, f(2)=2,  f(3)=1,f(4)=2,  
f(5)=1 
5 从上往下分析问题,从下往上解决问题。

代码:

package dataStructureAndAlgorithms;

public class DaymicPrograming {
	//递归方法
	public static int findMinCoinNumberByRecursion(int n){
		if(n == 1 || n == 3 || n == 5){
			return 1;
		}
		
		if(n == 2 || n == 4){
			return 2;
		}
		return min(findMinCoinNumberByRecursion(n-1),findMinCoinNumberByRecursion(n-3),findMinCoinNumberByRecursion(n-5)) + 1;
	}
	
	//从下往上的方法
	public static int findMinCoinNumberFromDownToUp(int n){
		int size = n>5?n:5;
		int[] minNumber = new int[size+1];
		minNumber[1] = minNumber[3] = minNumber[5] = 1;
		minNumber[2] = minNumber[4] = 2;

		for(int i=6;i<=n;i++){
			minNumber[i] =  min(minNumber[i-1],minNumber[i-3],minNumber[i-5]) + 1; 
		}
		
		return minNumber[n];
	}
	
	public static int min(int a, int b, int c){
		return a<b?(a<c?a:c):(b<c?b:c);
	}
	
	
	public static void main(String[] args) {
		for(int i=5;i<=30;i++){
			System.out.print("数额:" + i + ",递归算法计算出 最少硬币数:" + findMinCoinNumberByRecursion(i));
			System.out.println(", 从下往上的方法计算出最少硬币数:" + findMinCoinNumberFromDownToUp(i));
		}
	}
}

结果:

数额:5,递归算法计算出 最少硬币数:1, 从下往上的方法计算出最少硬币数:1
数额:6,递归算法计算出 最少硬币数:2, 从下往上的方法计算出最少硬币数:2
数额:7,递归算法计算出 最少硬币数:3, 从下往上的方法计算出最少硬币数:3
数额:8,递归算法计算出 最少硬币数:2, 从下往上的方法计算出最少硬币数:2
数额:9,递归算法计算出 最少硬币数:3, 从下往上的方法计算出最少硬币数:3
数额:10,递归算法计算出 最少硬币数:2, 从下往上的方法计算出最少硬币数:2
数额:11,递归算法计算出 最少硬币数:3, 从下往上的方法计算出最少硬币数:3
数额:12,递归算法计算出 最少硬币数:4, 从下往上的方法计算出最少硬币数:4
数额:13,递归算法计算出 最少硬币数:3, 从下往上的方法计算出最少硬币数:3
数额:14,递归算法计算出 最少硬币数:4, 从下往上的方法计算出最少硬币数:4
数额:15,递归算法计算出 最少硬币数:3, 从下往上的方法计算出最少硬币数:3
数额:16,递归算法计算出 最少硬币数:4, 从下往上的方法计算出最少硬币数:4
数额:17,递归算法计算出 最少硬币数:5, 从下往上的方法计算出最少硬币数:5
数额:18,递归算法计算出 最少硬币数:4, 从下往上的方法计算出最少硬币数:4
数额:19,递归算法计算出 最少硬币数:5, 从下往上的方法计算出最少硬币数:5
数额:20,递归算法计算出 最少硬币数:4, 从下往上的方法计算出最少硬币数:4
数额:21,递归算法计算出 最少硬币数:5, 从下往上的方法计算出最少硬币数:5
数额:22,递归算法计算出 最少硬币数:6, 从下往上的方法计算出最少硬币数:6
数额:23,递归算法计算出 最少硬币数:5, 从下往上的方法计算出最少硬币数:5
数额:24,递归算法计算出 最少硬币数:6, 从下往上的方法计算出最少硬币数:6
数额:25,递归算法计算出 最少硬币数:5, 从下往上的方法计算出最少硬币数:5
数额:26,递归算法计算出 最少硬币数:6, 从下往上的方法计算出最少硬币数:6
数额:27,递归算法计算出 最少硬币数:7, 从下往上的方法计算出最少硬币数:7
数额:28,递归算法计算出 最少硬币数:6, 从下往上的方法计算出最少硬币数:6
数额:29,递归算法计算出 最少硬币数:7, 从下往上的方法计算出最少硬币数:7
数额:30,递归算法计算出 最少硬币数:6, 从下往上的方法计算出最少硬币数:6


猜你喜欢

转载自blog.csdn.net/qq_31567335/article/details/79905952