Python 原语计算器的动态规划
我在处理这个问题,这和换硬币的问题很相似 我需要实现一个简单的计算器,它可以对当前数字x执行以下三个操作:将x乘以2、将x乘以3或将1与x相加 目标是给定一个正整数n,找到从数字1开始获得数字n所需的最小运算次数 我做了一个贪婪的方法,但它显示了不正确的结果Python 原语计算器的动态规划,python,dynamic-programming,greedy,Python,Dynamic Programming,Greedy,我在处理这个问题,这和换硬币的问题很相似 我需要实现一个简单的计算器,它可以对当前数字x执行以下三个操作:将x乘以2、将x乘以3或将1与x相加 目标是给定一个正整数n,找到从数字1开始获得数字n所需的最小运算次数 我做了一个贪婪的方法,但它显示了不正确的结果 import sys def optimal_sequence(n): sequence = [] while n >= 1: sequence.append(n) if n % 3
import sys
def optimal_sequence(n):
sequence = []
while n >= 1:
sequence.append(n)
if n % 3 == 0:
n = n // 3
elif n % 2 == 0:
n = n // 2
else:
n = n - 1
return reversed(sequence)
input = sys.stdin.read()
n = int(input)
sequence = list(optimal_sequence(n))
print(len(sequence) - 1)
for x in sequence:
print(x)
例如:
Input: 10
Output:
4
1 2 4 5 10
4个步骤。但正确的方法有三个步骤:
Output:
3
1 3 9 10
我读过关于动态规划的书,希望能在这里实现它。但是,我不知道如何在特定情况下正确使用它,有人能给我一个建议吗?只要用简单的递归解决它,然后: 代码: 提示:f(x)返回一个元组(a,b),其中
a
表示从1获得x的最小步骤,b
表示获得最佳解的前一个数字<代码>b仅用于打印解决方案
输出:
4 # solution for 10
1 3 9 10
7 # solution for 111
1 2 4 12 36 37 111
您可以调试我的代码并了解其工作原理。如果你是DP的初学者,你可以阅读我的另一篇关于DP的文章来快速入门
由于Python不能经常递归(大约10000次),因此我编写了一个迭代版本:
# only modified function print_solution(n) and solve(n)
def print_solution(n):
ans = []
while f(n)[1] != -1:
ans.append(n)
n = f(n)[1]
ans.append(1)
ans.reverse()
for x in ans:
print x,
def solve(n):
for i in range(1, n):
f(i)[0]
print_solution(n)
print ''
solve(96234) # 1 3 9 10 11 22 66 198 594 1782 5346 16038 16039 32078 96234
动态规划的主要思想是重用您以后预先计算的内容。有没有一种方法可以让已经计算过的较短序列帮助您更快地计算较长的序列?这里有一个问题,而不是最后一行中的解(10)。如果您真的解(96234),它会引发堆栈溢出错误。。如何克服这种“沙耶基斯”?请让我知道..@KishanB Python程序不能经常递归。。。我将为你们写一个迭代的例子……在“ans=(f(n-1)[0]+1,n-1”中,外括号是什么意思?@BrunoNegrãoZica
f(n)
返回(a,b)
,因此f(n)[0]
是的a
。
# only modified function print_solution(n) and solve(n)
def print_solution(n):
ans = []
while f(n)[1] != -1:
ans.append(n)
n = f(n)[1]
ans.append(1)
ans.reverse()
for x in ans:
print x,
def solve(n):
for i in range(1, n):
f(i)[0]
print_solution(n)
print ''
solve(96234) # 1 3 9 10 11 22 66 198 594 1782 5346 16038 16039 32078 96234