문제
길이가 n인 철근이 있을 때 이 철근을 팔아서 얻을 수 있는 이익의 최댓값을 구해보자 단, 철근은 길이 1에서 길이 n까지 정수의 길이로 나눠 판매할 수 있으며 길이별 가격표가 주어진다.
해결 방법
for (let i = 0; i < N; i++) {
maxValue[i] = Number.MIN_SAFE_INTEGER;
for (let j = 0; j <= i; j++) {
maxValue[i] = Math.max(maxValue[i], value[j]+maxValue[i-j]);
}
}
재귀 문제 풀이 로직 예) maxValue(4)
i=1, j=1
i=2, j=1, 2
i=3, j=1, 2, 3
i=4, j=1, 2, 3, 4
maxValue[i] = Math.max(maxValue[i], value[j]+maxValue[i-j]);
// i=1, j=1
maxValue[1] = Math.max(maxValue[1], value[1]+maxValue[1-1]);
// i=2, j=1, 2
maxValue[2] = Math.max(maxValue[2], value[1]+maxValue[2-1]);
maxValue[2] = Math.max(maxValue[2], value[2]+maxValue[2-2]);
// i=3, j=1, 2, 3
maxValue[3] = Math.max(maxValue[3], value[1]+maxValue[3-1]);
maxValue[3] = Math.max(maxValue[3], value[2]+maxValue[3-2]);
maxValue[3] = Math.max(maxValue[3], value[2]+maxValue[3-3]);
// i=4, j=1, 2, 3, 4
maxValue[4] = Math.max(maxValue[4], value[1]+maxValue[4-1]);
maxValue[4] = Math.max(maxValue[4], value[2]+maxValue[4-2]);
maxValue[4] = Math.max(maxValue[4], value[2]+maxValue[4-3]);
maxValue[4] = Math.max(maxValue[4], value[2]+maxValue[4-4]);
CODE
function maxValue(value, N) {
let maxValues = Array(value.length).fill(0)
// # STUDY1
// i: 철근 길이 1에서 N까지 계산해 증가
for (var i = 1; i <= N; i++) {
// # STUDY1
// j: 철근 길이 i인 철근은 i길이에 해당되는 가격표까지만 필요
console.log(`# 철근길이 ${i} 일때 최대 가격 구하는 중 `)
for (var j = 1; j <= i; j++) {
// # STUDY2
// i-j의 의미 : 원래 철근길이 i에서 길이 j만큼 자른다는 의미
// # STUDY3
// : i-j 길이의 최대 이익(maxValues[i - j])에 j길이 철근의 가격(value[j])을 더하면 i 길이 철근의 판매 가격을 구할 수 있다
// ( == value[j] + maxValues[i - j] )
// : 모든 j에 대해서 최댓값을 취하면 길이 i인 철근을 판매할 때의 최대 이익을 구할 수 있다.
// ( Math.max에 대한 설명 )
maxValues[i] = Math.max(maxValues[i], value[j] + maxValues[i - j])
console.log(
`Math.max(maxValues[${i}], value[${j}] + maxValues[${i} - ${j}])`
)
}
console.log("")
}
return maxValues[N]
}
var value = [0, 1, 5, 8, 9, 10, 17, 17, 20]
console.log(maxValue(value, value.length - 1))
CODE console 출력 결과
# 철근길이 1 일때 최대 가격 구하는 중
Math.max(maxValues[1], value[1] + maxValues[1 - 1])
# 철근길이 2 일때 최대 가격 구하는 중
Math.max(maxValues[2], value[1] + maxValues[2 - 1])
Math.max(maxValues[2], value[2] + maxValues[2 - 2])
# 철근길이 3 일때 최대 가격 구하는 중
Math.max(maxValues[3], value[1] + maxValues[3 - 1])
Math.max(maxValues[3], value[2] + maxValues[3 - 2])
Math.max(maxValues[3], value[3] + maxValues[3 - 3])
# 철근길이 4 일때 최대 가격 구하는 중
Math.max(maxValues[4], value[1] + maxValues[4 - 1])
Math.max(maxValues[4], value[2] + maxValues[4 - 2])
Math.max(maxValues[4], value[3] + maxValues[4 - 3])
Math.max(maxValues[4], value[4] + maxValues[4 - 4])
# 철근길이 5 일때 최대 가격 구하는 중
Math.max(maxValues[5], value[1] + maxValues[5 - 1])
Math.max(maxValues[5], value[2] + maxValues[5 - 2])
Math.max(maxValues[5], value[3] + maxValues[5 - 3])
Math.max(maxValues[5], value[4] + maxValues[5 - 4])
Math.max(maxValues[5], value[5] + maxValues[5 - 5])
# 철근길이 6 일때 최대 가격 구하는 중
Math.max(maxValues[6], value[1] + maxValues[6 - 1])
Math.max(maxValues[6], value[2] + maxValues[6 - 2])
Math.max(maxValues[6], value[3] + maxValues[6 - 3])
Math.max(maxValues[6], value[4] + maxValues[6 - 4])
Math.max(maxValues[6], value[5] + maxValues[6 - 5])
Math.max(maxValues[6], value[6] + maxValues[6 - 6])
# 철근길이 7 일때 최대 가격 구하는 중
Math.max(maxValues[7], value[1] + maxValues[7 - 1])
Math.max(maxValues[7], value[2] + maxValues[7 - 2])
Math.max(maxValues[7], value[3] + maxValues[7 - 3])
Math.max(maxValues[7], value[4] + maxValues[7 - 4])
Math.max(maxValues[7], value[5] + maxValues[7 - 5])
Math.max(maxValues[7], value[6] + maxValues[7 - 6])
Math.max(maxValues[7], value[7] + maxValues[7 - 7])
# 철근길이 8 일때 최대 가격 구하는 중
Math.max(maxValues[8], value[1] + maxValues[8 - 1])
Math.max(maxValues[8], value[2] + maxValues[8 - 2])
Math.max(maxValues[8], value[3] + maxValues[8 - 3])
Math.max(maxValues[8], value[4] + maxValues[8 - 4])
Math.max(maxValues[8], value[5] + maxValues[8 - 5])
Math.max(maxValues[8], value[6] + maxValues[8 - 6])
Math.max(maxValues[8], value[7] + maxValues[8 - 7])
Math.max(maxValues[8], value[8] + maxValues[8 - 8])
```
# call stack tree(상향식 접근방법)
![](./img/08_철근자르기_dynamicProgramming.jpg)