完全平方数
题目描述
给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...
)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
思路
最开始写了个递归dp,超时了。
这里可以用拉格朗日四平方和定理
定理内容: 每个正整数均可表示成不超过四个整数的平方之和
重要的推论:
- 数 n 如果只能表示成四个整数的平方和,不能表示成更少的数的平方之和,必定满足4^a(8b+7)
- 如果 n%4==0,k=n/4,n 和 k 可由相同个数的整数表示
因此,
- 先判断是否是4个整数组成,即验证4^a(8b+7),满足则结果为4
- 再判断是否为完全平方数,满足则结果为1
- 再判断能否由两个数的平方和组成,这里我使用的枚举的方法,满足则结果为2
- 以上都不符合,则结果为3
code
func numSquares(n int) int {
tn := n
for tn%4 == 0 {
tn /= 4
}
if tn%8 == 7 {
return 4
}
sq := (int)(math.Sqrt(float64(n)))
if sq*sq == n {
return 1
}
for i := sq; i >= 1; i-- {
sqs := n - i*i
sqsq := (int)(math.Sqrt(float64(sqs)))
if sqsq*sqsq+i*i == n {
return 2
}
}
return 3
}