ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Python-12865-평범한 배낭(시간 복잡도 개선)
    Problem Solving 2020. 12. 31. 00:34

    평범한 배낭 _ 시간복잡도 개선 click

    포스팅 했던 평범한 배낭 문제를 시간 복잡도가 낮은 방법으로 다시 풀어 보았다.

     

    Crepe

    3960ms는 기존 코드, 1508ms는 이번에 다시 푼 코드이다.

     

     


     

    먼저 기존에 포스팅 했던 방식의 코드는 어떻게 작동하는지 되짚어 보자.

    dp 배열에 무게 별로 담을 수 있는 최대 가치를 저장한다.

     

    • 초기 dp 값은 모두 0이다.
    • w의 무게와 v의 가치를 가지는 물건이 있을 때, 0 부터 k(버틸 수 있는 무게)-w 까지의 i에 대해서 dp[w+i] = max(dp[i] + v, dp[w+i])를 통해 업데이트 해 나간다.
    • 모든 물건에 대해 위와 같은 과정을 거치고, dp값들 중 최대값을 구하면 된다.

     

    문제의 예제 입력에 대해서 배낭에 넣을 수 있는 물건들의 가치의 최대값을 구하는 과정은 아래와 같다.

     

     

    • 빨간색 글씨는 각 물건에서 업데이트 되는 값이다.
    • 빨간색 칸들은 각 물건에서 탐색하게 되는 칸들이다.

     

    시간 복잡도가 개선된 코드는 어떻게 작동하는지 알아보자.

    dp Dictionary를 이용해 무게 별로 담을 수 있는 최대 가치를 저장한다.

    • 초기 dp는 {0: 0}이다.
    • w의 무게와 v의 가치를 가지는 물건이 있을 때, dp에 저장되어 있는 무게와 w를 더해 k를 초과하지 않는 경우의 무게의 합과 가치의 합을 임시로 저장해 놓는다. (tmp 배열에 저장한다.)
    • tmp 배열에 저장된 무게 tmp_w 와 가치 tmp_v에 대해서, dp에 tmp_w가 존재하지 않는 경우에는 dp[tmp_w] = tmp_v로 추가해준다.
    • dp에 tmp_w가 존재하는 경우에는 dp[tmp_w]에 이미 저장되어 있는 값이 tmp_v보다 작을 때만 dp[tmp_w] = tmp_v로 업데이트 해준다.
    •  

    Crepe

    • 빨간색 글씨는 각 물건에서 업데이트 되는 값이다.
    • 빨간색 칸들은 각 물건에서 탐색하게 되는 칸들이다.

     

    두 그림을 비교해 보자.
    Dictionary를 활용한 코드에서 각 물건에 대해 탐색하는 칸이 적다는 것을 확인할 수 있다.
    List를 활용한 코드에서는 각 물건에 대해 0 부터 k-w 까지 모두 탐색해나가야 하는 반면 Dictionary를 활용한 코드에서는 기존 dp에 저장되어있는 무게들만 탐색하기 때문에 효율적이다.

     

     

    CODE

    import sys
    read=sys.stdin.readline
    
    n,k=map(int,read().split())
    things=list(list(map(int,read().split())) for _ in range(n))
    
    dp=dict()
    dp[0]=0
    
    for w,v in things:
        #dp에 저장되어 있는 무게와 w를 더해 k를 초과하지 않는 경우의 
        #무게의 합과 가치의 합을 임시로 저장
        tmp=[]
        for dp_w, dp_v in dp.items():
            if dp_w + w <= k:
                tmp.append((dp_w + w,dp_v+v))
    
        for tmp_w, tmp_v in tmp:
            #tmp_w가 dp내에 존재하면, tmp_v가 기존 dp값보다 작을 때만 업데이트 한다.
            if tmp_w in dp:
                if dp[tmp_w] < tmp_v:
                    dp[tmp_w] = tmp_v
            #tmp_w가 dp내에 존재하지 않으면, 바로 업데이트 한다.
            else:
                dp[tmp_w] = tmp_v
    
    print(max(dp.values()))

     


    틀린 부분이 있을 수 있습니다. 피드백 주시면 고치도록 하겠습니다! 감사합니다.👍

    [꼭 다시 풀어보기]



    'Problem Solving' 카테고리의 다른 글

    Python - 1520 - 내리막길  (0) 2021.01.04
    Python-2098-외판원 순회  (0) 2021.01.03
    Python-2638-치즈  (0) 2020.12.30
    Python-2206-벽 부수고 이동하기  (0) 2020.12.28
    Python-1987-알파벳  (0) 2020.12.27
Designed by Tistory.