解法一:(动态规划)①定义:dp[i]表示能组合成i的最少硬币个数,dp[n+1] ②初始状态:dp[0]=0 dp[i]=Integer.MAX_VALUE ③状态转移方程:dp[i] = Math.min(min, dp[i - j*j])+1,因为每次循环都i++,之前的最小完全平方数加起来肯定不能到i,所以min必须+1
import java.util.*;
class Solution79 {
public int coinChange(int[] coins, int amount) {
int[] dp = new int[amount + 1];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[0] = 0;
for (int i = 1; i <= amount; i++) {
int min = Integer.MAX_VALUE;
for (int j = 0; j < coins.length; j++) {
if (coins[j] <= i && dp[i - coins[j]]!=Integer.MAX_VALUE) {
min = Math.min(min,dp[i - coins[j]]+1);
}
dp[i] = Math.min(dp[i], min);
}
}
if(dp[amount] == Integer.MAX_VALUE){
return -1;
}
return dp[amount];
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.nextLine().trim();
int amount = in.nextInt();
String[] split = s.split(",");
int[] coins = new int[split.length];
for (int i = 0; i < split.length; i++) {
coins[i] = Integer.parseInt(split[i]);
}
Solution79 sol = new Solution79();
System.out.println(sol.coinChange(coins, amount));
}
}
注意:
- 为了方便后续判断,
Arrays.fill(dp, Integer.MAX_VALUE);
Math.min(min, dp[i - coins[j]]==Integer.MAX_VALUE?Integer.MAX_VALUE:dp[i - coins[j]]+1)
取到这个数之前,要判断这个数是否为Integer.MAX_VALUE
,如果是的话,这个数不可取。- 每一个数都一定有【完全平方数】,但每一个数不一定有零钱和与之相等,需要初始化
Arrays.fill(dp, Integer.MAX_VALUE);
和判断dp[i - coins[j]]!=Integer.MAX_VALUE
- 初始化dp数组大小时,一般计算总数时是n+1,以**结尾为n+1;其余为n