动态规划 -- 零钱兑换(Java语言)

题目:零钱兑换

动态规划:dfs是自顶而下的递归,dp是自底而上的递推。动态规划将复杂问题拆分成若干子问题,每个子问题仅仅解决一次,并保存子问题的解,最后导出原问题的解。

用动规解决的问题通常具备以下两个特征:

1.最优子结构(最优化原理):通过求解子问题的最优解,可以获得原问题的最优解。

2.无后效性:
√ 某阶段的状态一旦确定,则此后过程的演变不再受此前各状态及决策的影响(未来与过去无关)
√ 在推导后面阶段的状态时,只关心前面状态的具体值,不关心该状态时怎么演变过来的

动态规划步骤:

1.定义状态:如dp[i]的含义

2.设置初始状态(边界):如dp[ 0 ]的值

3.确定状态转移方程:如dp[ i ]和dp[ i-1 ]的关系

题目描述:

假设有25分,20分,5分,1分的硬币,硬币数量不限,现要找给客户41分的零钱,如何办到使用硬币数量最少?

解析:

定义dp[n]为找给客户n分零钱需要的硬币最少。
假设第一次选择25分的,那么dp[n] = dp[n-25] + 1;
假设第一次选择20分的,那么dp[n] = dp[n-20] + 1;
假设第一次选择5分的, 那么dp[n] = dp[n-5] + 1;
假设第一次选择1分的, 那么dp[n] = dp[n-1] + 1;

在这四种情况中选出需要硬币最少的,这就确定了状态转移方程:
dp[n] = min{ dp[n-25], dp[n-20], dp[n-5],dp[n-1] } + 1;

方式一:

public class _01_零钱兑换_dp {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int N = in.nextInt(); //需要兑换的零钱
		in.close();
		
		int[] dp = new int[N + 1]; 
		for (int i = 1; i <= N; i++) { //dp[i]:兑换i分零钱需要的最少硬币
			int min = Integer.MAX_VALUE;
			if(i >= 1)  min = Math.min(dp[i] = dp[i-1], min); 
			if(i >= 5)  min = Math.min(dp[i] = dp[i-5], min);
			if(i >= 20) min = Math.min(dp[i] = dp[i-20], min);
			if(i >= 25) min = Math.min(dp[i] = dp[i-25], min);
			dp[i] = min + 1;
		}
		System.out.println(dp[N]);
	}
}

方式二:

public class _零钱兑换 {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int N = in.nextInt(); //录入零钱
		in.close();
		int[] faces = {1, 5, 20, 25};
		
		int[] dp = new int [N + 1];
		
		for (int i = 1; i <= N; i++) {
			int min = Integer.MAX_VALUE;
			for (int face : faces) {
				if (face > i) continue; // 给定的面值比要凑的面值还大, 跳过此轮循环
				min = Math.min(dp[i - face], min);
			}
			dp[i] = min + 1;
		}
		
		System.out.println(dp[N]);
	}
}

两种方式本质上并无差别。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值