【力扣】零钱兑换和零钱兑换2,动态规划算法
最大组合数和最小物品数
package day0325;
public class Demo2 {
public static void main(String[] args) {
int[] coins = {186, 419, 83, 408};
int amount = 6249;
int count = getMinCoinCount(amount, coins);
System.out.println(count);
}
private static int getMaxCombineCount(int amount, int[] coins) {
int[] dp = new int[amount + 1];
dp[0] = 1;
for (int i = 0; i < coins.length; i++) {
for (int j = coins[i]; j < dp.length; j++) {
dp[j] = dp[j] + dp[j - coins[i]];
}
}
return dp[amount];
}
private static int getMinCoinCount(int amount, int[] coins) {
int[] dp = new int[amount + 1];
for (int i = 0; i < dp.length; i++) {
dp[i] = amount + 1;
}
dp[0] = 0;
for (int coin : coins) {
for (int j = coin; j < dp.length; j++) {
dp[j] = Math.min(dp[j], dp[j - coin] + 1);
}
}
return dp[amount] > amount ? -1 : dp[amount];
}
}
打印最少数量组合
package day0325;
import java.util.*;
import java.util.stream.IntStream;
public class Demo1 {
public static void main(String[] args) {
int[] coins = {186, 419, 83, 408};
int amount = 6249;
System.out.println(186 + 186 + 186 + 419 + 419 + 419 + 419 + 419 + 83 + 83 + 83 + 83 + 408 + 408 + 408 + 408 + 408 + 408 + 408 + 408);
Map<Integer, List<Integer>> amountListMap = IntStream.rangeClosed(0, amount).collect(HashMap::new, (map, i) -> map.put(i, new ArrayList<>()), HashMap::putAll);
int[] dp = new int[amount + 1];
Arrays.fill(dp, amount + 1);
dp[0] = 0;
for (int i = 0; i < coins.length; i++) {
for (int j = 1; j < dp.length; j++) {
if (j >= coins[i]) {
int count = dp[j - coins[i]];
int newCount = Math.min(dp[j], count + 1);
if (newCount == count + 1) {
List<Integer> currentList = new ArrayList<>();
if (count == 0) {
currentList.add(coins[i]);
amountListMap.put(j, currentList);
} else {
List<Integer> otherList = amountListMap.get(j - coins[i]);
currentList.addAll(otherList);
currentList.add(coins[i]);
amountListMap.put(j, currentList);
}
}
dp[j] = newCount;
}
}
}
System.out.println(amountListMap.get(amount));
System.out.println("-----------------------------------------------------------------------------------------------");
System.out.println(dp[amount] > amount ? -1 : dp[amount]);
}
}
打印所有的组合
package day0325;
import java.util.*;
import java.util.stream.IntStream;
public class Demo3 {
public static void main(String[] args) {
int[] coins = {1, 2, 5};
int amount = 5;
Map<Integer, List<List<Integer>>> everyAmountCombineListMap = IntStream.rangeClosed(0, 5).collect(HashMap::new, (map, i) -> map.put(i, new ArrayList<>()), HashMap::putAll);
int[] dp = new int[amount + 1];
dp[0] = 1;
List<List<Integer>> zeroList = new ArrayList<>();
List<Integer> innerZeroList = new ArrayList<>();
innerZeroList.add(0);
zeroList.add(innerZeroList);
everyAmountCombineListMap.put(0, zeroList);
for (int i = 0; i < coins.length; i++) {
for (int j = coins[i]; j < dp.length; j++) {
List<List<Integer>> amountCombineList = new ArrayList<>();
if (j - coins[i] == 0) {
List<Integer> innerList = new ArrayList<>();
innerList.add(j);
amountCombineList.add(innerList);
} else {
int otherIndex = j - coins[i];
List<List<Integer>> otherList = everyAmountCombineListMap.get(otherIndex);
for (List<Integer> l : otherList) {
List<Integer> currentList = new ArrayList<>(l);
currentList.add(coins[i]);
amountCombineList.add(currentList);
}
}
if (dp[j] != 0) {
List<List<Integer>> otherList = everyAmountCombineListMap.get(j);
amountCombineList.addAll(otherList);
}
everyAmountCombineListMap.put(j, amountCombineList);
dp[j] = dp[j] + dp[j - coins[i]];
}
}
System.out.println(everyAmountCombineListMap);
System.out.println(everyAmountCombineListMap.get(amount));
System.out.println("--------------------------------------------------------------------------------------------------------------------");
System.out.println(everyAmountCombineListMap.get(amount).size());
System.out.println(dp[amount]);
}
}