最少硬币数
给定不同面额的硬币清单和总金额。 输出组成该数量所需的最少硬币数量。 如果不能使用给定的硬币弥补这笔钱,则输出-1。 可以假设每种类型的硬币数量都是无限的。
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Main{
private static int coinChange(int[] coins, int amount) {
if(amount == 0) {
return 0;
}
if(coins.length == 1 && (amount % coins[0] != 0 || amount < coins[0])) {
return -1;
}
//dp[k],得到k所需的最少硬币数
int[] dp = new int[amount+1];
for(int i = 1; i <= amount; i++) {
//这里Integer.MAX_VALUE-1无特殊意义,仅代表一个较大的数;
dp[i] = Integer.MAX_VALUE-1;
}
dp[0] = 0;
//从一开始遍历直到目标金额,维护每个金额所需的最少硬币数
for(int i = 1; i <= amount; i++) {
//对每种硬币金额都进行判断
for(int coin: coins) {
//如果当前硬币面值大于当前金额,也就不存在这样的情况,用这个硬币去比较进而更新最少硬币数
if(i < coin) {
continue;
}
//如果换成coin这个面值的硬币,是否可以用更少的硬币数
dp[i] = Math.min(dp[i], dp[i - coin]+1);
}
}
//如果dp[amount]还是初始化的值,即无法用硬币组成
if(dp[amount] == Integer.MAX_VALUE-1) {
return -1;
} else {
return dp[amount];
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int T = Integer.parseInt(scanner.nextLine());
for(int i = 0; i < T; i++) {
String[] str1 = scanner.nextLine().split(" ");
String[] str2 = scanner.nextLine().split(" ");
int n = Integer.parseInt(str1[0]);
int amount = Integer.parseInt(str1[1]);
int[] coins = new int[n];
for (int j = 0; j < n; j++) {
coins[j] = Integer.parseInt(str2[j]);
}
System.out.println(coinChange(coins, amount));
}
}
}