문제
체감 난이도(1~5) : 2.5
풀이
평범한 dp 문제. 풀이는 쉬우나 공간복잡도를 고려해줘야한다.
슬라이딩 윈도우 기법을 이용해 풀면 매우 효율적인 공간복잡도를 얻을 수 있다.
// 원래 풀이. 그냥 풀어도 통과 되긴했음.
memset(d,0,sizeof(d));
int ret = 0;
for(int i = 1 ; i <= m ; i++)
{
for(int j =0 ; j < n; j++)
{
if(i >= price[j])
{
int tmp = d[i - price[j]];
d[i] = max(d[i] , tmp + value[j]);
}
}
ret = d[i];
}
// 책에 있는 코드. 보고 배우자
int sushi3() {
int ret = 0;
c[0] = 0;
for(int budget = 1; budget <= m; ++budget) {
int cand = 0;
for(int dish = 0; dish < n; ++dish)
if(budget >= price[dish])
cand = max(cand, c[(budget - price[dish]) % 201] + pref[dish]); // % 연산을 이용해 이전에 사용했던 공간을 고대로 사용한다. 슬라이딩 윈도우 기법
c[budget % 201] = cand;
ret = max(ret, cand);
}
return ret;
}
배운 점
- 슬라이딩 윈도우 기법. 공간복잡도를 줄이는 효율적인 기법. 메모이제이션과 재귀를 이용한 dp에서는 쓰기 힘들지만 내가 주로 푸는 방법인 반복적 dp(bottom up) 방식에서 사용할 수 있다.
- 예제 )
d[n%2][x] =max( d[(n+1)%2][x] , d[(n+1)%2][x+1] ) + arr[n][x] - 문제에서 100 단위로 가격이 주어진다는 것을 생각해서 공간복잡도를 1/100 으로 줄였다. 문제를 잘 읽자.
Comments