[2022 KAKAO TECH INTERNSHIP] 코딩 테스트 공부

최민길(Gale)·2023년 3월 8일
1

알고리즘

목록 보기
51/172

문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/118668

[이 문제는 프로그래머스에서 푼 문제입니다.]
이 문제는 dp를 이용하여 문제를 풀 수 있습니다. 완전 탐색으로 문제를 접근하게 될 경우 모든 경우의 수를 변경해가며 결과를 체크해야하기 때문에 시간 초과가 발생합니다. 따라서 dp를 이용하여 최솟값을 저장하는 방식으로 문제를 풀어야 합니다.

  1. dp[i][j] = 알고력 i, 코딩력 j까지 도달하는데 최단 시간 으로 dp 배열을 설정합니다.
  2. 문제를 풀지 않고 학습할 경우 각각
    dp[i+1][j] = Math.min(dp[i+1][j],dp[i][j]+1);
    dp[i][j+1] = Math.min(dp[i][j+1],dp[i][j]+1);

    으로 dp배열을 채웁니다.
  3. 문제를 풀었을 때의 경우 기존값과 풀었을 때의 값의 최솟값을 계산합니다.
    dp[new_alp][new_cop] = Math.min(dp[new_alp][new_cop], dp[i][j]+cost);

다음은 코드입니다.

import java.util.*;

class Solution {
    public int solution(int alp, int cop, int[][] problems) {
        //  현재 문제들 중 알고력과 코딩력의 최댓값 저장
        int alm=0,com=0;
        for(int i=0;i<problems.length;i++){
            if(alm < problems[i][0]) alm = problems[i][0];
            if(com < problems[i][1]) com = problems[i][1];
        }
        
        // dp[i][j] = 알고력 i, 코딩력 j까지 도달하는데 최단 시간
        int[][] dp = new int[alm+1][com+1];
        
        // alp와 alm 중 최솟값부터 dp 배열 채우기 시작
        alp = Math.min(alp,alm);
        cop = Math.min(cop,com);
        
        // 초기값 dp[alp][cop] = 0;
        for(int i=0;i<alm+1;i++) Arrays.fill(dp[i],Integer.MAX_VALUE);
        dp[alp][cop] = 0;
        
        // dp[Math.min(alp,alm)][Math.min(cop,com)] 부터 dp[alm][com]까지 dp 배열 최신화
        for(int i=alp;i<=alm;i++){
            for(int j=cop;j<=com;j++){
                // 문제 풀지 않고 학습할 경우
                // 이 때 i,j가 위의 최댓값을 넘으면 안됨 (최댓값이 구하는 값이기 때문에)
                if(i<alm) dp[i+1][j] = Math.min(dp[i+1][j],dp[i][j]+1);
                if(j<com) dp[i][j+1] = Math.min(dp[i][j+1],dp[i][j]+1);
                
                // i와 j가 각각 alp_req, cop_req보다 크거나 같을 경우 문제 풀기 처리
                for(int k=0;k<problems.length;k++){
                    int alp_req = problems[k][0];
                    int cop_req = problems[k][1];
                    int alp_rwd = problems[k][2];
                    int cop_rwd = problems[k][3];
                    int cost = problems[k][4];
                    
                    if(i>=alp_req && j>=cop_req){
                        // new_alp,new_cop가 위의 최댓값을 넘으면 안됨 (최댓값이 구하는 값이기 때문에)
                        int new_alp = Math.min(i+alp_rwd, alm);
                        int new_cop = Math.min(j+cop_rwd, com);
                        
                        // 문제 풀었을 때 걸리는 비용과 현재값과의 최솟값 비교
                        dp[new_alp][new_cop] = Math.min(dp[new_alp][new_cop], dp[i][j]+cost);
                    }
                }
            }
        }
        
        return dp[alm][com];
    }
}

profile
저는 상황에 맞는 최적의 솔루션을 깊고 정확한 개념의 이해를 통한 다양한 방식으로 해결해오면서 지난 3년 동안 신규 서비스를 20만 회원 서비스로 성장시킨 Software Developer 최민길입니다.

0개의 댓글