[Programmers] P12905 사칙연산

Question

Language: Python

행렬최소곱셈횟수와 비슷한 유형의 문제로

아래와 같은 정규식을 통해 문제를 풀이를 할 수 있다. fi,j=min(fi,k operator fk+1,j)[i<=k<=j]

이때, operator는 중간에 위치한 연산자의 종류에 따라 가게 되므로 조건문을 통해 따로 분리해야한다. 아래의 예시를 통해, 경우에 따라 적용되는 연산자의 종류가 다른 것을 확인할 수 있다.

1 - 3 + 5

경우 1: (1-3) + 5
경우 2: 1 - (3+5)

또한, 행렬과 다르게 음수 * 음수의 결과를 통해 큰 양수가 나오는 경우가 발생하므로, 각각의 중간 연산 과정에서 min/max 값 두 개 모두 저장하고 아래와 같은 조합을 고려해야한다.

min op min
min op max
max op min
max op max

Solution

from math import inf
def solution(arr):
    operands=[]
    operators=[]

    for segment in arr:
        if segment in ["+","-"]:
            operators.append(segment)
        else:
            operands.append(int(segment))

    num=len(operands)    
    #각각의 공간에 대해서 최소,최대값을 저장한다.
    dp=[[[inf,-inf] for _ in range(num+1)] for _ in range(num+1)]
    
    #대각선(i,i)에 대해서는 자기 자신의 값을 저장한다.
    for i in range(1,num+1):
        dp[i][i][0]=operands[i-1]
        dp[i][i][1]=operands[i-1]

    for diagonal in range(1,num+1):
        for i in range(1,num-diagonal+1):
            j=i+diagonal
            tmp=[]
            for k in range(i,j):
                #중간 연산자가 + 인 경우
                if operators[k-1]=="+":
                    values=[dp[i][k][0]+dp[k+1][j][0],dp[i][k][0]+dp[k+1][j][1],dp[i][k][1]+dp[k+1][j][0],dp[i][k][1]+dp[k+1][j][1]]           
                    dp[i][j][0]=min(dp[i][j][0],min(values))
                    dp[i][j][1]=max(dp[i][j][1],max(values))
                #중간 연산자가 - 인 경우
                elif operators[k-1]=="-":
                    values=[dp[i][k][0]-dp[k+1][j][0],dp[i][k][0]-dp[k+1][j][1],dp[i][k][1]-dp[k+1][j][0],dp[i][k][1]-dp[k+1][j][1]]
                    dp[i][j][0]=min(dp[i][j][0],min(values))
                    dp[i][j][1]=max(dp[i][j][1],max(values))
    
    return max(dp[1][-1])

댓글남기기