문제 - 에어컨
에어컨을 통해 실내온도를 희망온도에 맞춰 올리거나 내릴 수 있다. 즉 냉방과 난방이 가능하다.
flag를 이용하여 냉방으로 하는지 난방으로 하는지 판단
그리고 t1,t2의 범위가 -10 ~40 이므로 이를 배열로 나타내기 어려우니 치환을 해주기 위해 +10을 해준다.
에어컨은 승객이 없는 경우에도 켜질 수 있으며 승객이 있는 경우에는 t1 ~ t2 온도로 맞춰놔야된다.
dp를 이용
dp[i][j] = i분에 j 온도를 맞추기 위한 최소 소비전력
경우의 수는 총 4가지가 있다.
1. 에어컨이 켜져있는 상태
- 실내온도와 희망온도가 같은 경우
- 실내온도와 희망온도가 다를 경우(실내온도를 희망온도 방향으로 맞춰야됨)
2. 에어컨이 꺼져있는 상태
- 실내온도와 실외온도가 같은 경우
- 실내온도와 실외온도가 다를 경우(실내온도를 실외온도 방향으로 맞춰야됨)
해당 경우의 수들 중에 가장 소비전력이 낮은 경우만 저장.
값의 결과는 dp 배열 중에서 가장 값이 낮은 것을 출력해주면 된다.
class Solution {
public int solution(int temperature, int t1, int t2, int a, int b, int[] onboard) {
//전력의 최대값
int k = 1000*100;
//온도 치환
t1 += 10;
t2 += 10;
temperature += 10;
int[][] dp = new int[onboard.length][51];
for (int i = 0; i < onboard.length; i++) {
for (int j = 0; j < 51; j++) {
dp[i][j] = k;
}
}
dp[0][temperature] = 0;
int flag = 1;
if (temperature > t2) {
flag = -1;
}
for (int i = 1; i < onboard.length; i++) {
for (int j = 0; j < 51; j++) {
int minV = k;
//승객이 없는 경우 or 승객이 있다면 t1 ~ t2로 온도 조절
if (( onboard[i] == 1 && t1 <= j && j <= t2 ) || onboard[i] == 0) {
//에어컨을 끈 경우
//1. 실내온도 != 실외온도
if (0 <= j+flag && j+flag <= 50) {
minV = Math.min(minV, dp[i-1][j+flag]);
}
//2. 실내온도 == 실외온도
if (j == temperature) {
minV = Math.min(minV, dp[i-1][j]);
}
//에어컨을 킨 경우
//1. 실내온도 != 희망온도
if (0 <= j-flag && j-flag <= 50) {
minV = Math.min(minV, dp[i-1][j-flag] + a);
}
//2. 실내온도 == 희망온도
if (t1 <= j && j <= t2) {
minV = Math.min(minV, dp[i-1][j] + b);
}
dp[i][j] = minV;
}
}
}
int i = onboard.length-1;
int answer = dp[i][0];
for (int j = 1; j < 51; j++) {
answer = Math.min(answer, dp[i][j]);
}
return answer;
}
}
DP문제는 어떻게 접근을 해야될지 할때마다 까먹는다.. 여러 문제를 풀어보면서 해봐야되겠다.