LeetCode 322. 零钱兑换
完全背包,且求组合数(非排列数
dp[j]: 找到 j 块钱所有的组合数
状态转移方程:dp[j] = min(dp[j], dp[j - coins[i]] + 1);
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
vector<int> dp(amount + 1, 0x3f3f3f3f);
dp[0] = 0;
for(int i = 0; i < coins.size(); i++){
for(int j = coins[i]; j <= amount; j++){
dp[j] = min(dp[j], dp[j - coins[i]] + 1);
}
}
return dp[amount] == 0x3f3f3f3f ? -1 : dp[amount];
}
};
LeetCode 279. 完全平方数
自己实现的一遍,求1-n之间的完全平方数浪费了太多时间和空间
class Solution {
public:
int numSquares(int n) {
//先求1-n间的完全平方数
vector<int> perfect_square;
for(int i = 1; i <= n; i++){
if(sqrt(i) == floor(sqrt(i))){
perfect_square.emplace_back(i);
}
}
vector<int> dp(n + 1, INT_MAX);
dp[0] = 0;
for(int i = 0; i < perfect_square.size(); i++){
for(int j = perfect_square[i]; j <= n; j++){
dp[j] = min(dp[j], dp[j - perfect_square[i]] + 1);
}
}
return dp[n];
}
};
看卡哥是不用求的, 而是在遍历的时候直接算完全平方数
1.先遍历物品,
class Solution {
public:
int numSquares(int n) {
vector<int> dp(n + 1, INT_MAX);
dp[0] = 0;
for(int i = 1; i <= sqrt(n); i++){
//先遍历物品
for(int j = i * i; j <= n; j++){
//再遍历背包
dp[j] = min(dp[j], dp[j - i * i] + 1);
}
}
return dp[n];
}
};
2.先遍历背包
class Solution {
public:
int numSquares(int n) {
vector<int> dp(n + 1, INT_MAX);
dp[0] = 0;
for(int j = 1; j <= n; j++){
//先遍历背包
for(int i = 1; i * i <= j; i++){
//再遍历物品
dp[j] = min(dp[j], dp[j - i * i] + 1);
}
}
return dp[n];
}
};