본문 바로가기

알고리즘/BOJ

[BOJ 16639] 괄호 추가하기 3

https://www.acmicpc.net/problem/16639

 

16639번: 괄호 추가하기 3

첫째 줄에 수식의 길이 N(1 ≤ N ≤ 19)가 주어진다. 둘째 줄에는 수식이 주어진다. 수식에 포함된 정수는 모두 0보다 크거나 같고, 9보다 작거나 같다. 문자열은 정수로 시작하고, 연산자와 정수가 번갈아가면서 나온다. 연산자는 +, -, * 중 하나이다. 여기서 *는 곱하기 연산을 나타내는 × 연산이다. 항상 올바른 수식만 주어지기 때문에, N은 홀수이다.

www.acmicpc.net

 

1. 연산자 우선순위 O

2. 연산자의 갯수 여러개 가능

3. 괄호의 중첩 O

 

3번 조건에 의해서 1번, 2번 조건은 신경 안써도 괜찮다.

1번 -> 우선순위는 괄호를 쳐서 무시하면 되고 ex) 1 + 3 * 2 -> (1 + 3) * 2

2번 -> 연산자가 여러개 있는 건 괄호가 연산자 우선순위대로 쳐져 있는 것과 동일하다 ex) 1 + 3 * 2 == 1 + (3 * 2)

 

어떤 두 식을 연산했을 때

양수 * 양수 = 양수

음수 * 양수 = 음수

양수 * 음수 = 음수

음수 * 음수 = 양수 임을 고려해서

최솟값끼리 연산했을 때 최대가 나올 수 있을 수도 있는 걸 잘 유의해야한다.

 

max_dp(i, j) = i부터 j까지 연산했을 때 최댓값

min_dp(i, j) = i부터 j까지 연산했을 때 최솟값

 

전형적인 O(N^3) dp를 완성하자. -> 유사한 문제 : 파일 합치기, 행렬의 곱셈 순서

 

N = int(input())
E = input()
M = N // 2 + 1
max_dp = [[-10 ** 9] * M for _ in range(M)]
min_dp = [[10 ** 9] * M for _ in range(M)]

for i in range(M):
    max_dp[i][i] = min_dp[i][i] = int(E[i * 2])

for k in range(1,M):
    for i in range(M - k):
        j = i + k
        for x in range(i, j):
            #최댓값
            max_dp[i][j] = max(max_dp[i][j], eval(str(max_dp[i][x]) + E[x * 2 + 1] + str(max_dp[x + 1][j])))
            
            max_dp[i][j] = max(max_dp[i][j], eval(str(min_dp[i][x]) + E[x * 2 + 1] + str(max_dp[x + 1][j])))
            
            max_dp[i][j] = max(max_dp[i][j], eval(str(max_dp[i][x]) + E[x * 2 + 1] + str(min_dp[x + 1][j])))
            
            max_dp[i][j] = max(max_dp[i][j], eval(str(min_dp[i][x]) + E[x * 2 + 1] + str(min_dp[x + 1][j])))

            #최솟값
            min_dp[i][j] = min(min_dp[i][j], eval(str(max_dp[i][x]) + E[x * 2 + 1] + str(max_dp[x + 1][j])))
            
            min_dp[i][j] = min(min_dp[i][j], eval(str(min_dp[i][x]) + E[x * 2 + 1] + str(max_dp[x + 1][j])))
            
            min_dp[i][j] = min(min_dp[i][j], eval(str(max_dp[i][x]) + E[x * 2 + 1] + str(min_dp[x + 1][j])))
            
            min_dp[i][j] = min(min_dp[i][j], eval(str(min_dp[i][x]) + E[x * 2 + 1] + str(min_dp[x + 1][j])))

print(max_dp[0][-1])

'알고리즘 > BOJ' 카테고리의 다른 글

[BOJ 2302] 극장 좌석  (0) 2020.04.25
[BOJ 15480] LCA와 쿼리  (0) 2020.04.24
[BOJ 5214] 환승  (0) 2020.04.21
[BOJ 2263] 트리의 순회  (0) 2020.03.11