动态规划

什么叫做动态规划

动态规划过程是:每次决策依赖于当前状态,又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划。

动态规划的思想

动态规划背后的思想很简单,和分治思想类似,将求解的问题分解成若干个子问题,按照顺序求解子问题,列出各种可能的局部解,通过决策(根据题意)保留那些有可能达到最优的局部解,丢弃其它局部解。为了减少重复计算,每个子问题只解一次,将其不同阶段的不同状态保存在一个二维数组中。但是,和分治算法不同的是,经过分解后得到的子问题往往不是互相独立的,而是下一个子阶段的求解建立在上一个子阶段的解的基础上

适用场景

   最优子结构性质;如果问题的最优解所包含的子问题的解也是最优的,就称该问题具有最优子结构性质(比如贪心算法就没有)

  无后效性;即子问题的解一旦确定,就不再改变,不受在这之后、包含它的更大的问题的求解决策影响

  子问题重叠性质;子问题重叠性质是指在用递归算法自顶向下对问题进行求解时,每次产生的问题并不总是新问题,有些子问题会被计算多次;(动态规划算法正是利用了这种子问题的重叠性质,,因为无后效性,所以对每个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次计算过的子问题的时候,在表格中查找一下结果就行了,从而很大的提升了效率)

具体问题

如果我们有面值为1元、3元和5元的硬币若干枚,如何用最少的硬币凑够11元?

假设 d[i] = j 表示凑够 i 元最少需要 j 个硬币,譬如说,当 i 为 0 的时候,需要 0 个硬币(废话),i 为 2 的时候需要 2 个硬币,i 为 3 的时候,出现两个方案,需要做一个选择,是选择 3 个 1 元硬币还是 1 个 3 元硬币,程序要怎么计算出来呢?递归!其实就是 d[3 - 1] (使用 1 元硬币之后,凑够 2 元所需要的最少数量)和 d[3 - 3](使用 3 元硬币之后,0元需要的最少硬币数量),取两者的最小值再加上 1 ; 

package com.threetop.www;


/**
 * 动态规划解决硬币组合问题
 * 有面值为1元、3元和5元的硬币若干枚,如何用最少的硬币凑够11元?
 * @author wjgs
 *
 */
public class DP {
	
	static int []coin={1,3,5};
	
	public static void dp_fun(int num)
	{
		 //动态规划表存储当前最优解
		int[]dp=new int[num+1];
		for (int i=1;i<dp.length;i++)
		{
			int min_val=Integer.MAX_VALUE;
			
			for(int j=0;j<coin.length;j++)
			{
				//动态规划的核心步骤
				if(i>=coin[j])
				{
					min_val=Math.min(dp[i-coin[j]]+1, min_val);
				}
					
					
			}
			    dp[i]=min_val;
		}
		for(int k=0;k<dp.length;k++)
		{
			System.out.println("凑齐"+k+"元,至少需要"+dp[k]+"枚硬币");
		}
		
		
	}
	

	public static void main(String[] args) {
		
		DP.dp_fun(11);
		

	}

}






阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页