【LeetCode279】完全平方数(完全背包问题)

举报
野猪佩奇996 发表于 2022/01/23 00:34:40 2022/01/23
【摘要】 文章目录 1.题目2.思路3.C++代码4.Python代码Reference 1.题目 2.思路 并没有让你输出所有满足情况的具体方案,问的是满足情况的(最少数目的)时的【平方数最...

1.题目

在这里插入图片描述

2.思路

并没有让你输出所有满足情况的具体方案,问的是满足情况的(最少数目的)时的【平方数最少的数量】,这种问题就是用dp了,和之前的拼硬币一样(每种币值的硬币不限量)是完全背包问题。
动态规划其实也就是遍历,只不过将中间值用空间储存起来了,便于计算了.

(1)确定状态
dp[i] 表示和为 i 的 nums 组合中完全平方数最少有 dp[i] 个.

(2)转移方程
确定状态转移方程需要2个意识:1)最后一步;2)子问题。
本题在dp入门中有讲,确定状态转移方程,如:若只有2元、5元、7元,现要拼成x元,状态转移方程就是 f ( x ) = m i n ( f ( x − 2 ) , f ( x − 5 ) , f ( x − 7 ) ) + 1 f(x)=min ( f(x-2),f(x-5),f(x-7) )+1 f(x)=min(f(x2),f(x5),f(x7))+1。具体转移方程见代码。

(3)初始条件+边界情况
初始化大小为n+1的数组,并且每个数组元素为0;特别的,n为0是数组元素值也是0。

(4)计算顺序
i和j都是从小到大。

3.C++代码

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 - i * i] + 1, dp[j]);
                }
            }
        }
        return dp[n];
    }
};

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

4.Python代码

class Solution:
    import math
    def numSquares(self, n: int) -> int:
        #dp[i] 表示和为 i 的 nums 组合中完全平方数最少有 dp[i] 个。
        dp = [float('inf')]*(n+1)
        dp[0] = 0
        #可供选则的nums列表 [1,4,9,...,sqrt(n)]  从中任意挑选数字组成和为n
        #完全背包
        for i in range(1, int(math.sqrt(n))+1):
            for j in range(n+1):
                if(j - i * i >= 0):
                    dp[j] = min(dp[j], dp[j-i*i]+1)
        return dp[n]

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

注意python中可以用这种方式表示正无穷和负无穷:

float("inf"), float("-inf")

  
 
  • 1

Reference

一文吃透动态规划

文章来源: andyguo.blog.csdn.net,作者:山顶夕景,版权归原作者所有,如需转载,请联系作者。

原文链接:andyguo.blog.csdn.net/article/details/118468526

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。