17.动态规划例题及解题步骤---最少硬币组合问题(求最大最小值动态规划)

一、题目:

输入:

    第一行:硬币面值数组a

    第二行:需组成的金额数m

输出:

    组成金额m所需的最少硬币数

例如:

输入:

[1,2,5]

11

输出:
3

二、分析:动态规划解题步骤包含四个部分

(1)部分一:确定状态

(1.1)最后一步

(1.2)子问题

(1.3)递归解法

(2)部分二:转移方程

(3)部分三:初始条件和边界情况

(4)第四部分:计算顺序(先计算每次计算都会用到的部分)

(5)小结

三、代码

import java.util.Scanner;

public class Main {
	/*  
测试数据

	 * */
	static int[] a = new int[3];//存放硬币面值(假设有三种面值)
	static int[] dp; //dp[i]组成金额i所需的硬币数(如果无法组成金额i,则设置为无穷)
	static int m;//组成的金额
	public static void main(String[] args){
		//1.输入相关数据
		Scanner sc = new Scanner(System.in);
		for(int i=0;i<3;i++) {
			a[i] = sc.nextInt();
		}
		m = sc.nextInt();
		dp = new int[m+1]; //金额0~m
		
		//2.获取dp数组的值
		dp[0]=0;//设置初值
		getDp();
		
		//3.输出组成金额m所需的硬币数
		System.out.println(dp[m]);
	}
	private static void getDp() {
		for(int i=1;i<=m;i++) {//dp[i],组成金额i所需的硬币数
			dp[i] = Integer.MAX_VALUE;//初始化该位置的值
			for(int j=0;j<a.length;j++) {//可选的硬币面值
				if(i>=a[j] && dp[i-a[j]]!=Integer.MAX_VALUE) {//关键!Integer.MAX_VALUE+1会越界,故排除这种情况;当前的金额数i应>=当前的硬币面值
					dp[i] = Math.min(dp[i-a[j]]+1,dp[i]);//最后dp[i]中存放了所需的最少硬币数。dp[i-a[j]]+1:因为用了硬币a[j],所以用的硬币数+1
				}
			}
		}
		
	}
	
}
	

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值