322. 零钱兑换
- dp[j] : 最小硬币数量, j 为金额(相当于背包空间)
- 递推公式 : dp[j] = min(dp[j - coins[i]] + 1, dp[j])
- 初始化: 需要一个最大值, 避免覆盖, dp[0] = 0
- 遍历顺序: 钱币有序无序不影响, 因为求解最小个数, 结果相同(先遍历物品后背包, 先背包后物品都可)
class Solution {
public:int coinChange(vector<int>& coins, int amount) {vector<int> dp(amount + 1, INT_MAX);dp[0] = 0;for (int i = 0; i < coins.size(); i++) {for (int j = 0; j <= amount; j++) {if (j - coins[i] >= 0 && dp[j - coins[i]] != INT_MAX) { //注意判断条件, 防溢出dp[j] = min(dp[j - coins[i]] + 1, dp[j]);}}}if (dp[amount] == INT_MAX) return -1;return dp[amount];}
};
279.完全平方数
- dp[j] : j 的最小数量为dp[j]
- 递推公式 : dp[j] = min(dp[j], dp[j - i * i] + 1)
- 初始化: 最大值避免覆盖, dp[0] = 0
class Solution {
public:int numSquares(int n) {vector<int> dp(n + 1, INT_MAX);dp[0] = 0;for (int i = 1; i * i <= n; i++) {for (int j = 1; j <= n; j++) {if (j - i * i >= 0) {dp[j] = min(dp[j], dp[j - i * i] + 1);}}}return dp[n];}
};
139.单词拆分