本题说硬币数量无限所以是完全背包问题
公式推导 如果知道了f(1) 到 f(i-1),那么f(i) = (min) F(i−cj)+1 cj是 coins[j]
import java.util.Arrays;
/**
* <p>给你一个整数数组 <code>coins</code> ,表示不同面额的硬币;以及一个整数 <code>amount</code> ,表示总金额。</p>
*
* <p>计算并返回可以凑成总金额所需的 <strong>最少的硬币个数</strong> 。如果没有任何一种硬币组合能组成总金额,返回 <code>-1</code> 。</p>
*
* <p>你可以认为每种硬币的数量是无限的。</p>
*
* <p> </p>
*
* <p><strong>示例 1:</strong></p>
*
* <pre>
* <strong>输入:</strong>coins = <code>[1, 2, 5]</code>, amount = <code>11</code>
* <strong>输出:</strong><code>3</code>
* <strong>解释:</strong>11 = 5 + 5 + 1</pre>
*
* <p><strong>示例 2:</strong></p>
*
* <pre>
* <strong>输入:</strong>coins = <code>[2]</code>, amount = <code>3</code>
* <strong>输出:</strong>-1</pre>
*
* <p><strong>示例 3:</strong></p>
*
* <pre>
* <strong>输入:</strong>coins = [1], amount = 0
* <strong>输出:</strong>0
* </pre>
*
* <p> </p>
*
* <p><strong>提示:</strong></p>
*
* <ul>
* <li><code>1 <= coins.length <= 12</code></li>
* <li><code>1 <= coins[i] <= 2<sup>31</sup> - 1</code></li>
* <li><code>0 <= amount <= 10<sup>4</sup></code></li>
* </ul>
* <div><div>Related Topics</div><div><li>广度优先搜索</li><li>数组</li><li>动态规划</li></div></div><br><div><li>👍 2002</li><li>👎 0</li></div>
*/
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public static int coinChange(int[] coins, int amount) {
int max = amount + 1;
int n = coins.length;
int[] dp = new int[amount + 1];
Arrays.fill(dp, max);
dp[0] = 0;
for (int i = 0; i < n; i++) {
for (int j = 1; j <= amount; j++)
if (j - coins[i] >= 0) {
dp[j] = Math.min(dp[j], dp[j - coins[i]] + 1);
}
}
return dp[amount] > amount ? -1 : dp[amount];
}
}
//leetcode submit region end(Prohibit modification and deletion)