力扣 279. 完全平方数

题目来源:https://leetcode.cn/problems/perfect-squares/description/

力扣 279. 完全平方数_第1张图片

C++题解(来源代码随想录): 动规五部曲分析如下:

  1. 确定dp数组(dp table)以及下标的含义。dp[j]:和为j的完全平方数的最少数量为dp[j]
  2. 确定递推公式。dp[j] 可以由dp[j - i * i]推出, dp[j - i * i] + 1 便可以凑成dp[j]。此时我们要选择最小的dp[j],所以递推公式:dp[j] = min(dp[j - i * i] + 1, dp[j]);
  3. dp数组如何初始化。dp[0]表示和为0的完全平方数的最小数量,那么dp[0]一定是0。非0下标的dp[j]应该是多少呢?从递归公式dp[j] = min(dp[j - i * i] + 1, dp[j]);中可以看出每次dp[j]都要选最小的,所以非0下标的dp[j]一定要初始为最大值,这样dp[j]在递推的时候才不会被初始值覆盖
  4. 确定遍历顺序。我们知道这是完全背包,如果求组合数就是外层for循环遍历物品,内层for遍历背包。如果求排列数就是外层for遍历背包,内层for循环遍历物品。本题是求最小数!都是可以的!
  5. 举例推导dp数组
class Solution {
public:
    int numSquares(int n) {
        vector dp(n + 1, INT_MAX);
        dp[0] = 0;
        for (int i = 0; i <= n; i++) { // 遍历背包
            for (int j = 1; j * j <= i; j++) { // 遍历物品
                dp[i] = min(dp[i - j * j] + 1, dp[i]);
            }
        }
        return dp[n];
    }
};
class Solution {
public:
    int numSquares(int n) {
        vector dp(n + 1, INT_MAX);
        dp[0] = 0;
        for (int i = 1; i * i <= n; i++) { // 遍历物品
            for (int j = i * i; j <= n; j++) { // 遍历背包
                dp[j] = min(dp[j - i * i] + 1, dp[j]);
            }
        }
        return dp[n];
    }
};

你可能感兴趣的:(开始C++吧,leetcode,算法,c++,动态规划,背包问题)