当前位置: 首页 > news >正文

动态规划----完全平方数(3种写法,逐步简化)

题目链接:完全平方数

完全平方数可以认为是完全背包问题。每一个平方小于n的平方数都是物品,而完全平方数之和n就是背包容量。每一个平方和都可以无限次使用。

写法1:把所有小于n的平方数存入数组nums,使用二维dp数组。

递推公式的推导可以看完全平方数

   int numSquares(int n) {
        int num = (int)sqrt(n);
        vector<int> nums(num, 0);
        //
        for(int i = 0; i<nums.size(); i++)
        {
            nums[i] = (i+1)*(i+1);
        }
        vector<vector<int>> dp(nums.size(), vector<int>(n+1, 0));
        //初始化第一列
        for(int i = 0; i<nums.size(); i++)
        {
            dp[i][0] = 0;
        }
        //初始化第一行
        for(int i=0; i<=n; i++)
        {
            dp[0][i] = i;
        }
        for(int i=1; i<nums.size(); i++)
        {
            for(int j=1; j<=n; j++)
            {
                if(j-nums[i]>=0)
                    dp[i][j] = min(dp[i-1][j], dp[i][j-nums[i]]+1);
                else
                    dp[i][j] = dp[i-1][j];
            }
        }
        return dp[nums.size()-1][n];
    }
写法2:把所有小于n的平方数存入数组nums,使用一维dp数组。
int numSquares(int n) {
        int num = (int)sqrt(n);
        vector<int> nums(num, 0);
        for(int i = 0; i<nums.size(); i++)
        {
            nums[i] = (i+1)*(i+1);
        }
        vector<int> dp(n+1, 0);
        for(int i=0; i<=n; i++)
        {
            dp[i] = i;
        }
        for(int i=1; i<nums.size(); i++)
        {
            for(int j=1; j<=n; j++)
            {
                if(j-nums[i]>=0)
                    dp[j] = min(dp[j], dp[j-nums[i]]+1);
            }
        }
        return dp[n];
    }
写法三、不用nums数组,先遍历背包,再遍历物品。因为:

dp[j] 可以由dp[j - i * i]推出, dp[j - i * i] + 1 便可以凑成dp[j]。
此时我们要在所有满足i*i<j的i中选择最小的dp[j],所以递推公式:dp[j] = min(dp[j - i * i] + 1, dp[j]);

int numSquares(int n) {
        vector<int> 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];
    }

相关文章:

  • cursor中使用prettier-code formatter插件方法
  • 六十天前端强化训练之第十七天React Hooks 入门:useState 深度解析
  • 基于 GEE 利用 Sentinel-1 双极化数据计算 SDWI 指数实现逐月提取水域面积
  • CFD交易与传统股票交易在交易机制上存在哪些显著差异
  • 矩阵交换行(信息学奥赛一本通-1119)
  • Compose笔记(九)--Checkbox
  • 【eNSP实战】使用高级ACL实现单向Ping
  • 基于UniApp + Vue3开发的智能汉字转拼音工具
  • 【前端三剑客】万字总结JavaScript
  • 【6*】差分约束系统学习笔记
  • nerfstudio以及相关使用记录(长期更新)
  • 【STM32】NVIC(嵌套向量中断控制器)
  • 【蓝桥】-动态规划-倒水
  • AI Agent席卷B端:解锁部门效率新玩法,挑战企业软件的智能革命
  • Git常用操作之GitLab
  • 元萝卜 1.0.9| 免root无限多开,支持Xposed模块和微信平板模式
  • 热修复框架Tinker与Robust原理剖析
  • python 类的相关知识, 介绍一下类的定义,创建类的实例,构造方法,创建类的成员并访问,以及访问限制的知识
  • 深搜专题10:组合
  • AI与.NET技术实操系列:ML.NET篇
  • 刘国中出席第78届世界卫生大会并致辞
  • 王缉慈|迈向近零的产业集群需加强利益相关者合作行动
  • 《远山淡影》改编电影入围戛纳关注单元,张怡微谈石黑一雄
  • 翻越高山,成为高山!浙江广厦成CBA历史第八支夺冠球队
  • 财政部:4月份中央收入增长1.6%,今年以来首月实现正增长
  • 在越剧之乡嵊州,浙江音乐学院越剧学院成立