티스토리 뷰

요약

  • 분할 정복을 위한 점화식 만들기

풀이과정

문제 풀이 방법은 금방 떠올린데 반해, 코드를 깔끔하게 다시 짜는데에 있어서 좀 많이 애먹었다.

시간도 오래 걸렸다.

1. 숫자와 연산자 분리하기

이렇게 안해도 되는데 직관적인 코딩을 위해 분리하였다.

void init(vector<string> arr, vector<int> &nums, vector<string> &ops) {
    // 숫자와 연산자로 나눠 저장
    for(int i = 0; i < arr.size(); i++) {
        if(i%2 == 0) {
            nums.push_back(stoi(arr[i]));
        }
        else {
            ops.push_back(arr[i]);
        }
    }
}

2. 풀 방법 정하기

나는 Bottom-Top 방식의 문제풀이 방법을 택했다.

가장 작은 단위의 연산은 최대값이 명백하게 정해져있다.

이를 이용해 Top까지 올라간다.

 

숫자 크기의 2차원 배열을 2개 max_dp, min_dp로 선언한다. 하나는 max, 하나는 min값을 저장한다.

매번 max, min 을 통해 비교해줄것이기 때문에 초기화값은 아주 큰 음수와 양수로 한다.

이들 값의 중앙값은 무조건 숫자 본인이 된다.

이 예제의 경우

1      
  3    
    5  
      8

이 저장된다는 얘기다.

이 순서로 채워넣는 것을 반복할 수 있다.(이전 값을 쓰기 때문에.)

1 -2    
  3 8  
    5 13
      8

이렇게? 물론 저 단계까지는 max_dp, min_dp 모두 같기 때문에...

이후부터는 max와 min 값이 달라지게 된다.

 

여기서 기존 배열을 채우는 방법이 아니라, 대각선으로 내려가는 방식으로 채워야 하기 때문에 코드를 참 더럽게 짰었다.

https://school.programmers.co.kr/questions/35224

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

그런데 이 분의 설명에서 답을 찾았다.

step이라는 변수를 추가하는 것...!

그냥 이분의 해설과 같은 풀이이므로 이 해설을 보는 게 나을 듯.

코드

#include <bits/stdc++.h>
using namespace std;

const int INF = 9e8;

void init(vector<string> arr, vector<int> &nums, vector<string> &ops) {
    // 숫자와 연산자로 나눠 저장
    for(int i = 0; i < arr.size(); i++) {
        if(i%2 == 0) {
            nums.push_back(stoi(arr[i]));
        }
        else {
            ops.push_back(arr[i]);
        }
    }
}

int solution(vector<string> arr)
{
    
    int answer = -1;
    vector<int> nums;
    vector<string> ops;
    
    init(arr, nums, ops);
    
    int max_dp[nums.size()][nums.size()];
    int min_dp[nums.size()][nums.size()];  
    
    for(int step = 0; step < nums.size(); step++) {
        for(int i = 0; i < nums.size() - step; i++) {
            int j = i + step;
            if(step == 0) {
                max_dp[i][j] = nums[i];
                min_dp[i][j] = nums[i];
            } else {
                max_dp[i][j] = -INF;
                min_dp[i][j] = INF;
                for(int k = i; k < j; k++) {
                    // dp(i,k) dp(k+1,j)
                    // 연산자 검사 ops[k]
                    if(ops[k] == "+") {
                        //max = max + max
                        max_dp[i][j] = max(max_dp[i][j], max_dp[i][k] + max_dp[k+1][j]);
                        //min = min + min
                        min_dp[i][j] = min(min_dp[i][j], min_dp[i][k] + min_dp[k+1][j]);
                    }
                    else {
                        //max = max - min
                        max_dp[i][j] = max(max_dp[i][j], max_dp[i][k] - min_dp[k+1][j]);
                        //min = min - max
                        min_dp[i][j] = min(min_dp[i][j], min_dp[i][k] - max_dp[k+1][j]);                        
                    }
                }
            }
            
        }
    }
    
//     for(int i = 0; i < nums.size(); i++) {
//         for(int j = 0; j < nums.size(); j++)
//             cout << max_dp[i][j] << " ";
//         cout << endl;
//     }
    answer = max_dp[0][nums.size()-1];
    
    return answer;
}

효율성은 이정도로 나왔다.

다른 사람의 풀이

 

 

'■ 알고리즘 > ◻ Programmers' 카테고리의 다른 글

[C++]디스크 컨트롤러  (0) 2023.03.10
[C++]등굣길  (0) 2023.03.10
[C++]전력망을 둘로 나누기  (0) 2023.03.01
[C++]주식 가격  (1) 2023.01.06
[C++] 다리를 지나는 트럭  (0) 2023.01.05
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/11   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30
글 보관함