목차

사칙연산

ps
링크programmers.co.kr/…
출처프로그래머스
문제 번호1843
문제명사칙연산
레벨Level 4
분류

동적 계획법

시간복잡도O(n)
인풋사이즈n <= 201
사용한 언어Python
해결날짜2020/12/25

풀이

코드

코드 1 - O(n) 방식

"""Solution code for "Programmers 1843. 사칙연산".

Greedy solution, running in O(n).
- Problem link: https://programmers.co.kr/learn/courses/30/lessons/1843
- Solution link: http://www.teferi.net/ps/problems/programmers/1843
"""


def solution(arr):
    cur_sum = prev_max = prev_sum = 0
    for sign, num in zip(arr[-2::-2], arr[-1::-2]):
        num = int(num)
        if sign == '+':        
            cur_sum += num
        else:
            prev_max = -num + max(cur_sum + prev_max, -cur_sum + prev_sum)
            prev_sum += cur_sum + num
            cur_sum = 0
    return int(arr[0]) + cur_sum + prev_max

코드 2 - O(n^3) 의 DP

"""Solution code for "Programmers 1843. 사칙연산".

DP solution, running in O(n^3).
- Problem link: https://programmers.co.kr/learn/courses/30/lessons/1843
- Solution link: http://www.teferi.net/ps/problems/programmers/1843
"""

INF = float('inf')


def solution(arr):
    n = len(arr) // 2 + 1
    dp_max = [[-INF] * n for _ in range(n)]
    dp_min = [[INF] * n for _ in range(n)]
    for i, num in enumerate(arr[::2]):
        dp_max[i][i] = dp_min[i][i] = int(num)
    sign = arr[1::2]

    for l in range(1, n):
        for i in range(n - l):
            j = i + l
            for k in range(i, j):
                if sign[k] == '+':
                    dp_max[i][j] = max(dp_max[i][j],
                                       dp_max[i][k] + dp_max[k + 1][j])
                    dp_min[i][j] = min(dp_min[i][j],
                                       dp_min[i][k] + dp_min[k + 1][j])
                else:
                    dp_max[i][j] = max(dp_max[i][j],
                                       dp_max[i][k] - dp_min[k + 1][j])
                    dp_min[i][j] = min(dp_min[i][j],
                                       dp_min[i][k] - dp_max[k + 1][j])
    return dp_max[0][-1]