만두맨두
만두 개발자 되다.
만두맨두
전체 방문자
오늘
어제
  • 분류 전체보기 (27)
    • 면접준비 (2)
    • GitHub (1)
    • JavaScript (5)
    • TypeScript (6)
    • REACT (1)
    • 에러 해결일지 (2)
    • 알고리즘 (7)
      • 이론 (4)
      • 자료구조 (1)
      • 프로그래머스 (2)
    • 만두의 일기 (1)
    • 프로젝트 (2)
      • 팀블로그 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • TypeScript
  • 대괄호 표기법
  • Beakjoon
  • 다이나믹 프로그래밍
  • 00018-easy-tuple-length
  • TellingUs
  • length
  • 자바스크립트
  • Algorithm
  • 타입챌린지
  • eslint
  • dynamic programming
  • 배열의 길이
  • hoisting
  • JavaScript
  • 프로그래머스
  • 점 표기법
  • node.js
  • JS
  • react
  • 호이스팅
  • PriorityQueue
  • dp
  • 우선순위큐
  • 타입 챌린지
  • telling me
  • programmers
  • type-challenges
  • frontend
  • 네임스페이스

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
만두맨두

만두 개발자 되다.

알고리즘/이론

배낭 문제 (Knapsack Problem)

2022. 11. 25. 16:41

배낭에 담을 수 있는 무게의 최대값이 정해져 있고,

가치와 무게가 정해져 있는 짐을 배낭에 담을 때,

가치의 합이 최대가 되도록하는 짐의 조합을 찾는 문제

 

1. 물건을 쪼갤 수 없어서 무게와 가치가 무조건 정수형태를 가지는 유형

다이나믹 프로그래밍(DP, Dynamic Programming)을 사용해야 한다.

 

EX ) 최대 무게는 7이고, 각 물건의 무게와 가치는 다음과 같다.

          =>  [6, 13], [4, 8], [3, 6], [5, 12]

 

1) 가로는 가방의 최대 무게 / 세로는 가방에 들어간 물건의 개수이다.

j   /   i 0 1 2 3 4 5 6 7
0 0 0 0 0 0 0 0 0
1                
2                
3                
4                

 

2) [6, 13] 물건을 집어 넣는다.

  0 1 2 3 4 5 6 7
0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 13 13
2                
3                
4                

   - 최대 무게가 현재 무게보다 작은 경우 ( DP[1][2] )

       => 바로 위의 값을 가져온다 ( DP[0][2] )

   - 최대 무게가 현재 무게보다 크거나 같은 경우 ( DP[1][7] )

       => 바로 위의 값 ( DP[0][7] ) /  현재 가치 ( 13 ) + [ 최대 무게 - 현재 무게 ] 위치의 가치 ( DP[0][1] ) 를 비교한다.

 

❗점화식 ❗

   현재 집어 넣는 물건의 가치 : v

   현재 집어 넣는 물건의 무게 : w

 

   ( w > j ) DP[i][j] = DP[i-1][j]

   (w <= j ) DP[i][j] = Math.max(DP[i-1][j], v + DP[i-1][j-w])

 

3) [4, 8] 물건을 집어 넣는다.

  0 1 2 3 4 5 6 7
0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 13 13
2 0 0 0 0 8 8 13 13
3                
4                

 

4) [3, 6] 물건을 집어 넣는다.

  0 1 2 3 4 5 6 7
0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 13 13
2 0 0 0 0 8 8 13 13
3 0 0 0 6 8 8 13 14
4                

 

5) [5, 12] 물건을 집어 넣는다.

  0 1 2 3 4 5 6 7
0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 13 13
2 0 0 0 0 8 8 13 13
3 0 0 0 6 8 8 13 14
4 0 0 0 6 8 12 13 14

 

자바스크립트 코드

const fs = require('fs');
const filePath = process.platform==='linux' ? '/dev/stdin':'input.txt';
const input = fs.readFileSync(filePath).toString().split('\n');

const [n, k] = input[0].split(' ').map(Number);
const objects = input.slice(1).map((v) => v.split(' ').map(Number));

let dp = Array.from(Array(n+1), () => Array(k+1).fill(0));

for (let i = 1; i <= n; i++) {
  const [w, v] = objects[i-1];
  
  for (let j = 1; j <= k; j++) {
    if (w > j) {
      dp[i][j] = dp[i-1][j];
    } else {
      dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-w] + v);
    }
  }
}

console.log(dp[n][k]);

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

유클리드 호제법 (Euclidean algorithm)  (0) 2023.02.19
가장 긴 증가하는 부분 수열 (LIS problem)  (0) 2023.01.19
최장 공통 부분 수열 (LCS problme)  (0) 2022.12.20
    '알고리즘/이론' 카테고리의 다른 글
    • 유클리드 호제법 (Euclidean algorithm)
    • 가장 긴 증가하는 부분 수열 (LIS problem)
    • 최장 공통 부분 수열 (LCS problme)
    만두맨두
    만두맨두
    프론트엔드 개발자가 되고 싶다 !

    티스토리툴바