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.单词拆分