#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
class Solution {
public:
int numSquares(int n) {
//因为要把0排除在外,对应下标1-n
vector<int> dp(n + 1);
//默认初始化都为0,这样数字1在进入循环时,dp[0]+1正好为1的对应值
for (int i = 1; i <= n; i++)
{
//INT_MAX代表了一个非常大的数值,初始化Min为这个值意味着在进入内层循环之前,Min持有不可能被超越的最大可能值。
//这样设计是因为算法的后续步骤需要找到能够使得dp[i]取值最小的那个j(即最小的完全平方数个数),
//初始化为最大整数可以确保任何实际计算出来的最小值都会比这个初始值小,从而可以正确更新Min的值。
int Min = INT_MAX;
for (int j = 1; j * j <= i; j++)
{
//min()比较当前值与dp[i-j*j]的大小关系
Min = min(Min, dp[i - j * j]);
}
dp[i] = Min + 1;
}
return dp[n];
}
};
int main()
{
Solution s;
cout<<s.numSquares(12);
system("pause");
}
依旧是dp动态规划,dp[i]的含义是,和为i的完全平方数的最少数量,由于组成n的数肯定大于1小于等于根号下n,又因为n由平方数组成,所以每次用i减去j*j,剩下的数必定小于i,小于i意味着可以直接从dp中提取,所以i=j*j+(组成i-j*j的完全平方数),且j从1到根号下i,进行循环,每次取最小值。