简单说明Python实现

时间:2018-04-25 20:07:49

标签: python python-3.x algorithm performance

程序有一个寄存器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之前,我在所有情况下都免除了该规则。有没有更有效的方法来做到这一点?

1 个答案:

答案 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