【Leetcode】完全背包-279. 完全平方数
题目
给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。
完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。
思路
- 完全背包问题:完全平方数就是物品 可以无限次使用,背包的容量就是n
- 确定dp数组以及下标的含义:dp[j]:凑满容量为j的背包所用最少完全平方数的个数
- 每一个元素都初始化为最大值 防止状态转换时dp[j]被覆盖
- dp[j]由两种方式得到:一种是放入完全平方数,那么dp[j] = dp[j - i * i] + 1 ,另一种就是不放入完全平方数 dp[j]不变
- dp[j] = min(dp[j],dp[j - i * i] + 1)
代码
class Solution {
public:
int numSquares(int n) {
// 完全背包问题:完全平方数就是物品 可以无限次使用,背包的容量就是n
// 确定dp数组以及下标的含义:dp[j]:凑满容量为j的背包所用最少完全平方数的个数
vector<int> dp(n + 1,INT_MAX);// 每一个元素都初始化为最大值 防止状态转换时dp[j]被覆盖
dp[0] = 0;
// dp[j]由两种方式得到:一种是放入完全平方数,那么dp[j] = dp[j - i * i] + 1
// 另一种就是不放入完全平方数 dp[j]不变
// 本题求解的是最少数量 不是组合或者排列问题 所以先遍历背包 在遍历物品 还是反过来 都是可以的
// dp[j] = min(dp[j],dp[j - i * i] + 1)
// 先遍历背包 在遍历物品
// 我们注意一下物品的数量 最大是n 那么就可以理解为每一个物品都是1
for(int i = 1; i <= n; i++)
{
for(int j = 1; j * j <= i;j++)
{
dp[i] = min(dp[i],dp[i - j * j] + 1);
}
}
return dp[n];
}
};