问题描述
Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...
) which sum to n.
For example, given n = 12
, return 3
because 12 = 4 + 4 + 4
; given n = 13
, return 2
because 13 = 4 + 9
.
算法分析
考虑Sum = a + b + c + d
,a,b,c,d均是perfect square number,用F[Sum]
表示最小numbers
,即F[Sum] =3
。
1、对于b + c + d,F[Sum-a] + 1 = F[Sum]
,同样F[c+d] + 1 = F[b+c+d]
,F[d] + 1 = F[c+d]
。
2、从1可以看出这就是动态规划的思想,定义状态F[N]
,状态转移方程为:F[N] = min(F[Sum-i^2]+1) ( i=1,2,3...N^(1/2) )
。
3、返回的F[N]即为the least number of perfect square numbers。
C++实现
int numSquares(int n) {
if (n <= 0) return 0;
// cntPerfectSquares[i]表示和为i的Perfect Squares. 从i=1开始计算,动态规划的思想计算所有子解
static vector<int> cntPerfectSquares({0});
// 计算cntPerfectSquares[i]知道i = n,即cntPerfectSquares.size() == n+1
while (cntPerfectSquares.size() <= n) {
int m = cntPerfectSquares.size();
int cntSquares = INT_MAX;
for (int i = 1; i*i <= m; i++)
cntSquares = min(cntSquares, cntPerfectSquares[m - i*i] + 1);
cntPerfectSquares.push_back(cntSquares);
}
return cntPerfectSquares[n];
}