力扣刷题-完全平方数

题目来自力扣

与之前做的:抢劫银行、买卖股票、表示数字……这些动态dp有所不同。

先给出这题的题目:

        给你一个整数 n ,返回 和为 n 的完全平方数的最少数量

以下是题目中的两个示例:

输入:n = 12
输出:3 
解释:12 = 4 + 4 + 4

输入:n = 13
输出:2
解释:13 = 4 + 9

刚看到这道题的时候,就想到一个定理:四平方和定理

        内容:每个正整数都可以表示为至多4个正整数的平方和。 如果把0包括进去,就正好可以表示为4个数的平方和。 (拉格朗日和欧拉分别在1770年和1773年作出最后的证明)

由此,最终结果大致就限制在4及以内.

我在这给出最暴力的方法之一,暴力嘛,带点dp规划很正常:

        思路:创建一个n+1个元素的数组,存储小于n的所有情况的个数,类似于打表,然后遍历n减去一个平方数的可能结果,加上对应位置的结果,找到这些可能结果的最小值即可。

例如:n=4,那么创建的数组中就是

         这里每一个数字前面的加一就是对dp的步数调整,也就是至少要多走一步,后面的加数就是4 - i^2得到的可能的得数对应的已知步数,取所有可能的最小值即可。

给出算法的实现:

int numSquares(int n) 
{
    int arr[n + 1];    // 创造一个一维数组,记录比输入数字小的所有的可能情况 
    arr[0] = 0;		 // 初始定义为 0  
    for (int i = 1; i <= n; i++) 
	{
        int min = INT_MAX;
        for (int j = 1; j * j <= i; j++) 
		{
            // 动态规划往后每一格需要的最小的平方数的个数 
            min = fmin(min, arr[i - j * j]);
   
        }	// 比 n 小的每一个数字都有相应的个数唯一表示,往后其实就只是往前找表相加而已
 
        arr[i] = min + 1;     // 加一维护次数的变化 
    }
    return arr[n];
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值