Closed baexxbin closed 2 weeks ago
승객이 탑승 중인 시간에 쾌적한 실내온도를 유지하기 위한 최소 소비전력 구하기
2 <= onboard <= 1,000
이기 때문에 승객이 타 있는 시간에 에어컨 온도 내림, 유지, 올림 모든 경우를 고려한다면 최대 3^1000
가지 경우의 수가 나올 것이라고 생각함 → 시간 초과
onboard
배열의 크기를 고려하여 시간 내에 문제 풀이할 수 있는 방법 생각해야 됨 → DP1. 외부온도와 내부온도가 같냐 / 다르냐
, 2. 온도 변화 처리
를 고려해야 됨
t1
, t2
, temperature
값 재조정
temperature
값을 재조정dp
배열에서 인덱스 확인을 할 수 있도록 외부 온도를 0
으로 설정하고, 0
도에서 t2
도 까지 확인하도록 함 dp
배열 채워주기
문제가 잘 안풀려서 가장 이해가 잘 되는 풀이를 보면서 문제랑 풀이 둘 다 이해해보려고 했는데요 ,,, 완벽하게 이해되지는 않네요 ㅠㅠ!!,,,
- 이해 안되는 부분 1) 처음
temperature
값 재조정 과정- 이해 안되는 부분 2) dp배열 열의 크기를 t2 +1이 아닌 t2 + 2로 해야되는 이유
- 이해 안되는 부분 3) 다른 풀이도 봐봤는데, 직관적으로 와닿는 풀이가 없음,,,,
헝헝헝,,,,,, 문제가 잘 안풀리니까 우울하네요 문제 풀이 기깔나게 해 주실 스피드웨건 구해요,,,,,,,,,,,,,,,,, 그리디, DP 어렵다ㅇ아악ㄱㄱ1!!!!!!! 😱
재귀, 백 트래킹
DP
로 변환해서 풀이int[][] dp = new int[onboard.length][51];
dp[i][j]
: i번째 깊이에서 j온도를 만드는 최소 전력값// 사람이 탔을 때, 적절한 온도가 아니라면 스킵
if (onboard[i] == 1 && !isPossible(j, t1, t2)) {
continue;
}
i
깊이의 j
번째 온도에서 다음 깊이i+1
의 온도를 결정해줘야 함
if (onboard[i] == 1 && !isPossible(j, t1, t2)) {
continue;
}
// 에어컨을 가동하지 않았을 때
if (j < temperature && j < 50) {
dp[i + 1][j + 1] = Math.min(dp[i + 1][j + 1], dp[i][j]);
} else if (j > temperature && j > 0) {
dp[i + 1][j - 1] = Math.min(dp[i + 1][j - 1], dp[i][j]);
} else {
dp[i + 1][j] = Math.min(dp[i + 1][j], dp[i][j]);
}
// 에어컨을 가동했을 때
if (j > 0)
dp[i + 1][j - 1] = Math.min(dp[i + 1][j - 1], dp[i][j] + a);
if (j < 50)
dp[i + 1][j + 1] = Math.min(dp[i + 1][j + 1], dp[i][j] + a);
dp[i + 1][j] = Math.min(dp[i + 1][j], dp[i][j] + b);
int min = INF;
for (int i = 0; i < 51; i++) {
// 가능한 값들 중 최솟값 찾기
if (onboard[len - 1] == 1 && !isPossible(i, t1, t2))
continue;
min = Math.min(min, dp[len - 1][i]);
}
세상에... 처음에 재귀로 방향 잘못 잡아서 한참 걸렸습니다.. 재밌는 문제였네요. 근데 왜 dp값 결정할 때, 현재 값을 결정하면 틀리고 다음 값을 결정하는 방식으로 하면 맞을까요... 의문
해설을 참고해 dp로 돌아옴
bottom-up
)
참고한 개념에선 이게 중요한 요소로 이용한 것 같았는데 최종 코드에선 딱히 큰 역할은 안하는듯...
dp[i][j] = k
: i분에 j도로 만들 수 있는 최소 전력 k
// 온도를 1도 낮추기
if (j > 0) {
int cost = (j - 1 < temperature) ? a : 0; // 외부온도보다 낮출 온도가 낮아서 온도조절이 필요하면 a비용 들어감
dp[i + 1][j - 1] = Math.min(dp[i + 1][j - 1], dp[i][j] + cost); // 그 다음 시간에 온도를 내린 비용은, 기존 최소 비용과 현재 최소 전력비용에 cost더한 값 중 작은 값
}
// 온도를 유지
int stayCost = (j == temperature) ? 0 : b; // 에어컨 끈 상태에서 비용
dp[i + 1][j] = Math.min(dp[i + 1][j], dp[i][j] + stayCost); // 이전에 계산한 기존 비용 vs 온도 유지시 비용
// 온도를 1도 높이기
if (j < 50) {
int cost = (j + 1 > temperature) ? a : 0; // 외부온도보다 높일 온도가 높아서 온도조절이 필요하면 a비용 들어감
dp[i + 1][j + 1] = Math.min(dp[i + 1][j + 1], dp[i][j] + cost); // 그 다음 시간에 온도를 올린 비용은, 기존에 계산해놓은 비용과 현재 온도를 높인 비용 중 최소 값
}
해설... 기대하겠습니다 엇 저도 dp[i][j]를 기준으로 점화식을 이어가고 싶었는데....! 의문입니다,,
2 ≤ onboard의 길이 ≤ 1,000
적정온도 -10 ≤ t1 < t2 ≤ 40
특정 시간의 특정 온도일 때 필요한 최소 전력 찾기
에어컨 ON
에어컨 OFF
3. 현재의 값으로 다음 값을 저장하는 `Bottom-up` 방식으로 진행
**현재 온도에 따라 다음의 온도를 내릴지, 올릴지 변경 되므로 `Bottom-up` 방식**으로 메모이제이션