1.题目描述
输入一个数字,令一些数的平方的和等于这个数字,找出数量最小的这样的数,返回最小数量。
比如输入12,则有12=4+4+4,于是返回3。输入16,则有16=16,所以返回1。
2.解题思路
这道题在LeetCode上依然是动态规划的分类,所以使用动态规划可以很方便的解出这道题。
首先是找出子问题,这里的子问题的分解可以是:C(n, i) = min(C(n - i * i, i - 1) + 1, C(n, i - 1))。
其中这里C(n, i)返回的是数n在区间[1, i]上面选择的数字序列的最小数量。所以,一个C(n, i)可以分解为是否选择i,然后分为两个子问题C(n - i * i, i - 1)以及C(n, i - 1),前者选择了数字i,而后者没有选择。
所以,为了减少重复计算,假设输入的数字是n,那么我们可以从1算起,一直算到n,算1是为了算2做铺垫,算2是为了算3做铺垫,依次类推。而且,可以减少重复计算的可能,因为3所需的都在2哪里算好了,不必多次去算2。
代码如下:
#include <iostream>
#include <vector>
using namespace std;
class Solution {
public:
int numSquares(int n) {
vector<int> results({0});
for (int i = 1; i <= n; i = i + 1) {
int result = i;
int num = i;
for (int j = 1; j * j <= i; j = j + 1) {
result = min(result, results[num - j * j] + 1);
}
results.push_back(result);
}
return results[n];
}
};
int main() {
cout << Solution().numSquares(32) << endl;
}