Closed yeongleej closed 1 month ago
🤔 시간복잡도 고려사항 n=5000(사탕 종류) m=100.00(입력 예산) 100 (정수 변환) 5000 10,000 = 50,000,000 -> 완전 탐색 불가 -> `O(nm)`
💡 풀이 아이디어
구매한 사탕 칼로리가 더 높은 사람이 이기는 문제 -> 그리디?
사탕을 분할할 수 없음 -> 그리디X -> DP
dp 점화식
for(int j = price; j <= m; j++) {
dp[j] = Math.max(dp[j], dp[j - price] + calories);
}
int m = (int) (temp * 100 + 0.5); // 변환하는 이유 : `rounding error`
배낭 문제 rounding error 해야하는 이유 : https://www.acmicpc.net/board/view/82054
쪼갤 수 없는
을 보자마자 0-1 KnapSack
0.01 ≤ m ≤ 100.00
의 소수점으로 인해 인덱스 계산이 어려움이 있으므로 정수화를 한 후에 진행
int m = (int) Math.round(Double.parseDouble(st.nextToken()) * 100);
0.01
을 정확히 저장하지 못하고 0.00999999...
와 같은 값으로 저장될 수 있음
부동소수점 값을 정수로 변환하는 과정에서 오차가 발생할 가능성이 있으므로, 이를 방지하기 위해 Math.round를 사용해 반올림 처리하는 것이 좋습니다. -chatGPT-
🤔 시간복잡도 고려사항
💡 풀이 아이디어
실수인 가격을 정수화하기
int m = (int)((실수)*100 + 0.5)
dp 활용
dp[i] = max(dp[i], dp[i-p])
🤔 시간복잡도 고려사항
O(사탕 종류의 수)
에 가능💡 풀이 아이디어
Candy
: 사탕의 칼로리, 가격을 저장하는 객체dp[i][j]
: i번째 사탕까지 고려하고, j원까지 쓸 수 있을 때, 살 수 있는 최대 칼로리냅색 알고리즘
for(int i = 1; i < dp.length; i++) {
for(int j = 0; j < dp[0].length; j++) {
if(j >= candys[i].p) {
dp[i][j] = Math.max(candys[i].c + dp[i][j - candys[i].p], dp[i - 1][j]);
} else {
dp[i][j] = dp[i - 1][j];
}
}
}
가격을 형변환하고 round하는 부분에서 잘 이해가 되지 않았는데, 지영님 댓글 보고 이해했습니다!!!!
🤔 시간복잡도 고려사항
O(N*M)
(N:사탕 수, M: 최대 돈)💡 풀이 아이디어
처음엔 01배낭 문제를 떠올렸으나, 사탕을 원하는 만큼 구매
할 수 있기에 완전 배낭 문제
01배낭 문제
: 아이템 0 or 1개 선택완전 배낭 문제
: 아이템 여러번 선택 가능dp 점화식
dp[i] = k
: i원으로 얻을 수 있는 최대 칼로리 k점화식 차이
01배낭 문제
완전 배낭 문제
가격 정수화 주의
01배낭과 완전 배낭에 대한 학습을 더 해봐야할 것 같다! 다들 이슈에 잘 정리해주신 덕분에 가격 형변환 잘 이해하고갑니다!
🤔 시간복잡도 고려사항
1 ≤ n ≤ 5,000
, 돈 100 ≤ m ≤ 10000
(소수점제거)
O(n * m)
= O(5000 * 10000) = O(50,000,000) = 10^7
💡 풀이 아이디어