一、题目:
输入:
第一行:硬币面值数组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
}
}
}
}
}