1. 첫 번째 시도
처음 문제를 봤을 때 들었던 생각은 재귀를 이용한 완전탐색.
const fs = require('fs');
const Data = fs.readFileSync('/dev/stdin').trim()
.split("\\n").map(v => v.split(" ").map(Number));
const [N,K] = Data.shift()
Data.sort((a,b)=>b[1] - a[1])
let answer = 0;
function additem(bag,index,w,v) {
if(index === N){
if(answer < v){
answer = v
}
return
}
const newbag = [...bag]
additem([...newbag],index+1,w,v)
const [W,V] = Data[index]
if(W+w <= K){
newbag.push(V)
additem([...newbag],index+1,w+W,v+V)
}
}
additem([],0,0,0)
console.log(answer)
백준에선 런타임 에러(TypeError)라고 떴다. 그건 둘째치고 애초에 이 문제를 풀 때 재귀를 이용하게 된다면 2^100이라는 시간복잡도를 가지게 되는 만큼 절때 풀 수 없다.
2. 두 번째 시도
이 문제는 1차원 배열로 DP를 만들기에는 변수가 무게, 가치 두가지로 주어져 불가능 했다.
그래서 2차원 배열로 만들면 어떨까라는 생각으로 접근하였고, 2차원 배열로 만들면 쓸데없이 순회하는 구조가 될 것 같아서 Map 객체로 생성하여 아래와 같이 코드를 작성하였다.
const fs = require('fs');
const Data = fs.readFileSync('/dev/stdin').toString().trim().split("\\n").map(v => v.split(" ").map(Number))
const [N, K] = Data.shift()
const arr= Array.from({length:N},()=>new Map())
const [a, v] = Data[0]
arr[0].set(a,v)
let answer
if(a <= K){
answer = v;
}else {
answer = 0;
}
for(let i=1; i<N; i++){
const [W, V] = Data[i]
if(W <= K){
arr[i].set(W,V)
if(answer < V){
answer = V
}
}
for(let [key,value] of arr[i-1]){
if(! arr[i].get(key) ||
arr[i].get(key) < value){
arr[i].set(key,value)
}
if(key+W <= K){
if(!arr[i].get(key+W) ||
arr[i].get(key+W) < value + V){
arr[i].set(key+W,value+V)
if(answer < value+V){
answer = value+V
}
}
}
}
}
console.log(answer)
간단하게 설명한다면 물건들을 순회하는데, 순회 하는 물건의 이전 물건들을 통해서 만들 수 있는 {무게 : 최대가치}를 저장하는 방식.
4 7
6 13
4 8
3 6
5 12
위와 같은 input이 주어진다면,,
첫번째 순회의 객체는 {6:13}
두번째는 {6:13, 4:8, 10:21} 여기서 최대무게가 7이기 때문에 {4:8, 6:13}이 된다.
세번째는 {6:13, 4:8, 3:6 ,9:19, 7:14} 무게제한 ⇒ {6:13, 4:8, 3:6 , 7:14}
마지막 {6:13, 4:8, 3:6 , 7:14, 5:12 ,11:25, 9:20, 8:18, 12:26} 무게제한 ⇒ {6:13, 4:8, 3:6 , 7:14, 5:12}
해서 최대 가치값은 14가 된다.
다시 코드를 보니 첫번째 물건을 Map객체에 넣고, 순회를 i=1로 시작했는데 불필요한 코드인 것 같다. 그냥 i=0으로 시작하면 될 듯.
'알고리즘 > 백준' 카테고리의 다른 글
백준 JS 1005번 ACM Craft. DP (0) | 2023.06.09 |
---|---|
백준 JS 2565번 전깃줄 DP (0) | 2023.06.09 |
백준 JS 1520번 내리막 길. DP + DFS (0) | 2023.06.09 |
백준 JS 9251번 LCS. 최장 공통 부분 수열 (0) | 2023.06.02 |
백준 JS 1931번 회의실 배정. 그리디 (0) | 2023.05.21 |