1.简述:

描述

给定数组arr,arr中所有的值都为正整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱数,求组成aim的最少货币数。

如果无解,请返回-1.

数据范围:数组大小满足 #yyds干货盘点# 动态规划专题:兑换零钱_数组 , 数组中每个数字都满足 #yyds干货盘点# 动态规划专题:兑换零钱_数组_02#yyds干货盘点# 动态规划专题:兑换零钱_数组_03

要求:时间复杂度 #yyds干货盘点# 动态规划专题:兑换零钱_i++_04 ,空间复杂度 #yyds干货盘点# 动态规划专题:兑换零钱_i++_05

输入描述:

第一行给定两个正整数分别是 n 和 aim 分别表示数组 arr 的长度和要找的钱数。

第二行给定 n 个正整数表示 arr 数组中的所有元素

输出描述:

输出组成 aim 的最少货币数

示例1

输入:

3 20
5 2 3

输出:

4

说明:

最少用四个 5 元凑成 20 元
示例2

输入:

3 0
5 2 3

输出:

0

示例3

输入:

2 2
3 5

输出:

-1

说明:

无解

2.代码实现:

import java.util.Arrays;
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
int n = reader.nextInt();
int aim = reader.nextInt();
int[] arr = new int[n + 1];
for (int i = 1; i <= n; i++) {
arr[i] = reader.nextInt();
}
int[] dp = new int[aim + 1];
// 完全背包
Arrays.fill(dp, Integer.MAX_VALUE - 10001);
dp[0] = 0;
for (int i = 1; i <= aim; i++) {
for (int j = 1; j <= n; j++) {
if (i >= arr[j]) {
dp[i] = Math.min(dp[i - arr[j]] + 1, dp[i]);
}
}
}
if (dp[aim] == Integer.MAX_VALUE - 10001)
System.out.println(-1);
else
System.out.println(dp[aim]);
}
}