题目5:给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
解法1
class Solution:
def __init__(self,n):
self.n=n
self._dp = [0]
def numSquares(self):
dp = self._dp
while len(dp) <= self.n:
dp += list((min(dp[-i*i] for i in range(1, int(len(dp)**0.5+1))) + 1,))
return dp[self.n]
if __name__=='__main__':
n=int(input())
sol=Solution(n)
print(sol.numSquares())
解法2
class Solution:
def __init__(self,n):
self.n=n
def numSquares(self):
"""
:type n: int
:rtype: int
"""
q = list()
q.append([self.n, 0])
visited = [False for i in range(self.n+1)]
visited[self.n] = True
while any(q):
num, step = q.pop(0)
i = 1
tNum = num - i**2
while tNum >= 0:
if tNum == 0:
return step + 1
if not visited[tNum]:
q.append((tNum, step + 1))
visited[tNum] = True
i += 1
tNum = num - i**2
if __name__=='__main__':
n=int(input())
sol=Solution(n)
print(sol.numSquares())
解法3
class Solution:
def __init__(self,n):
self.n=n
self._dp = list()
def numSquares(self):
"""
:type n: int
:rtype: int
"""
dp = self._dp
dp = [float('inf') for i in range(n + 1)]
dp[0] = 0
for i in range(self.n + 1):
j = 1
while i + j**2 <= self.n:
dp[i + j**2] = min(dp[i + j**2], dp[i] + 1)
j += 1
return dp[self.n]
if __name__=='__main__':
n=int(input())
sol=Solution(n)
print(sol.numSquares())
解法4
class Solution:
def __init__(self,n):
self.n=n
def numSquares(self):
#py中通过,py3超时
maxn = int(self.n ** 0.5)
dp = [i for i in range(self.n + 1)]
for i in range(1,maxn + 1):
for j in range(i * i,self.n + 1):
dp[j] = min(dp[j],dp[j - i * i] + 1)
return dp[self.n]
if __name__=='__main__':
n=int(input())
sol=Solution(n)
print(sol.numSquares())
解法5
class Solution:
def __init__(self,n):
self.n=n
def numSquares(self):
#@fibonacciWH 大佬的四平方定理做法
#四平方定理: 任何一个正整数都可以表示成不超过四个整数的平方之和。
#推论:满足四数平方和定理的数n(四个整数的情况)
#必定满足 n=4^a(8b+7)
while self.n % 4 == 0:
self.n /= 4
if self.n % 8 == 7:
return 4
a = 0
while a**2 <= self.n:
b = int((self.n - a**2)**0.5)
if a**2 + b**2 == self.n:
return (not not a) + (not not b)
a += 1
return 3
if __name__=='__main__':
n=int(input())
sol=Solution(n)
print(sol.numSquares())
解法6
import itertools
def n_sum(array,n,target):
ans=[]
for i in itertools.combinations(array,n):
if sum(i)==target:
ans.append(i)
ans_len=len(ans)
return ans,ans_len
def num_s(n):
array=[]
for i in range(1,n):
array.append(i**2)
array4=array+array+array+array#Lagrange 四平方定理: 任何一个正整数都可以表示成不超过四个整数的平方之和。
if n in array4:
return 1
else:
for i in range(2,5):
ans,ans_len=n_sum(array4,i,n)
if ans_len>0:
return i
break
if __name__=='__main__':
n=int(input())
print(num_s(n))