尝试使用递归解决此problem,但输入7168得到错误答案。
给定正整数n,找到总和为n的最小正方数(例如,1,4,9,16 ......)。
例如,给定n = 12,返回3,因为12 = 4 + 4 + 4;给定n = 13,返回2,因为13 = 4 + 9。
def recursive(self, n, result, dp):
if n in dp:
return dp[n]
#very large number
large_no = 1 << 31
if n < 1:
return 0
#checking if n is a square or not?
r = n**0.5
if int(r)*int(r) == n:
return result + 1
#iterate from square root till 1 checking all numbers
r = int(r)
while r >= 1:
large_no = min(large_no, self.recursive(n - int(r)*int(r), result + 1, dp))
r -= 1
#memoize the result
dp[n] = large_no
return large_no
我在上面调用函数:self.recursive(7168,0,{})
答案应该是4但我得到5.请不要建议其他方法来解决这个问题,因为我已经尝试过它并且它有效。我在这里只是知道这个逻辑的问题。
答案 0 :(得分:1)
我认为问题在于您将result
传递到递归中,但在记忆时不考虑它。
recursive(X, Y, dp)
和recursive(X, Z, dp)
如果dp[X]
返回X in dp
,但如果dp[X] + y
是dp[X] + z
,则分别返回dp[X]
和y = R - Y
还没有记忆(z = R - Z
和R
,result
dp[X]
的值result
。{/ p>
我会完全摆脱def recursive(self, n, dp):
if n in dp:
return dp[n]
#very large number
large_no = 1 << 31
if n < 1:
return 0
#checking if n is a square or not?
r = n**0.5
if int(r)*int(r) == n:
return 1
#iterate from square root till 1 checking all numbers
r = int(r)
while r >= 1:
large_no = min(large_no, self.recursive(n - int(r)*int(r), dp))
r -= 1
#memoize the result
dp[n] = large_no + 1
return large_no + 1
:
HttpClient
答案 1 :(得分:1)
首先,您有一个拼写错误:m
应为large_no
。
但是您错误地使用dp
:您应该以最小的方式缓存i
作为平方和,但您实际上是在缓存任何路径的结果你碰巧到了那里。
这意味着你可能会缓存一个比预期更大的值,而你的算法是错误的。虽然算法是错误的,但7168是产生错误结果的第一个值。
删除result
参数,将return result+1
更改为return 1
并将您的递归调用更改为:
large_no = min(large_no, 1+self.recursive(n - int(r)*int(r), dp))
代码的清理工作版本:
def recursive(n, dp):
if n in dp:
return dp[n]
if n == 0: return 0
best = n
for r in xrange(int(n**0.5), 0, -1):
best = min(best, 1 + recursive(n - r*r, dp))
dp[n] = best
return dp[n]