程序有一个寄存器X,初始化为0,仅支持3条指令:
LDI v:将立即值v加载(存储)到X中 ADD v:将立即值v添加到X并将结果存储在X中。 SQR:平方X的值并将结果存储在X中。
一个简短指令序列将如何影响价值的一个例子:
Instruction X
LDI 5 5
ADD 2 7
SQR 49
ADD -4 44
LDI -3 -3
SQR 9
我需要解决的问题是跳过选定的指令,以便在程序结束时获得X
的最大可能值。
到目前为止我所拥有的:
def prog(n):
x = 0
arr = []
for i in range(n):
itm = input().split()
arr += [(itm)]
#arr_rev = arr[::-1]
#limit = arr_rev.index(["SQR"])+len(arr)-1
limit = len(arr) - 1 - arr[::-1].index(['SQR'])
for i in range(len(arr)):
if i < limit:
if arr[i][0] == "ADD":
x += int(arr[i][1])
elif arr[i][0] == "LDI":
x = int(arr[i][1])
elif arr[i][0] == "SQR":
x = x**2
else:
if arr[i][0] == "ADD" and int(arr[i][1]) > 0:
x += int(arr[i][1])
elif arr[i][0] == "LDI" and int(arr[i][1]) > x:
x = int(arr[i][1])
elif arr[i][0] == "SQR":
x = x**2
return x
由于我不想添加负数,我会跳过这些。我也不想加载小于当前X
的数字。
然而,平方负数会使其成为正数,因此上述策略可能无法在所有情况下都有效。在我通过最后一个SQR之前,我在所有情况下都免除了该规则。有没有更有效的方法来做到这一点?
答案 0 :(得分:1)
如果&#34;效率更高&#34;,则表示&#34;可能正确&#34;,然后是。您当前的代码不适用于所有输入。有了SQR&#34;外卡&#34;,您无法轻易知道您正在查看的操作是否有益。例如
LDI 1
ADD -8
LDI 2
ADD -1
ADD 3
SQR
最大值来自(-8 + -1)^ 2。您应该使用动态编程(请参阅第一条评论中提供的链接)来跟踪所有&#34;最佳可能&#34;每一步的结果。
您通过递归例程对此进行经典编程,该例程在考虑每条指令时尝试两个分支:在最终答案中使用/不使用该指令。然后重复使用当前值X
和剩余的指令列表。
如果您想要进行数据流分析,可以应用各种快捷方式。例如,在任何ADD
指令流中,您可以将所有负值和所有正值组合成一个ADD
。如果您有LDI
,则可以考虑新值是真值还是绝值值 - 后者是通过SQR
推动改进的原因。
坦率地说,我建议做bisect-recur-dynamic_programming路线。
<强>更新强>
我更多地考虑了这一点。虽然DP是解决大问题的方法,但这不是不你想要先攻击的东西(在我看来)。相反,攻击是否包括每个特定命令的问题。您需要同时执行这两项操作,直到进一步完善。您甚至不能保证要包含SQR
命令:后续的减法可能会使其不合需要。
递归的逻辑是这样的:
def optimize(x_reg, command_list):
# x_reg current value of the X register
# command_list remaining list of commands
# base case
if len(command_list) == 0
return x_reg
# recursion case
op = command_list[0][0]
if op == "ADD":
new_x = x_reg + command_list[0][1]
elif op == "LDI":
new_x = command_list[0][1]
else: # op == "SQR":
new_x = x_reg * x_reg
with_op = optimize(new_x, command_list[1:]) # Use the command
sans_op = optimize(x_reg, command_list[1:]) # Don't use the command
return max(with_op, sans_op) # Return the larger of the two solutions found