Too Early To Stop
Main
About
Portfolio
Blog
Light
Thumbnail Image
BOJ#12865 - 평범한 배낭 Review
#Algorithm
#Dynamic Programming
2020년 12월 8일

최초 풀이 방법

처음 AC를 받은 소스 코드

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

int getResult(int index, int weight);
int cache[101][100001], stuff[2][100], n, k;

int main() {
  scanf("%d %d", &n, &k);
  fill(&cache[0][0], &cache[100][100001], -1);

  for (int i = 0; i < n; i++)
    scanf("%d %d", &stuff[0][i], &stuff[1][i]);

  printf("%d \n", getResult(-1, 0));

  return 0;
}

int getResult(int index, int weight) {
  if (weight > k) return numeric_limits<int>::min();

  int &ret = cache[index + 1][weight];
  if (ret != -1) return ret;

  ret = 0;
  for (int i = index + 1; i < n; i++)
    ret = max(ret, stuff[1][i] + getResult(i, weight + stuff[0][i]));

  return ret;
}

해결 방법

우선, 이와 같이 배낭에 담을 수 있는 무게의 최댓값이 정해져 있고, 일정 가치와 무게가 있는 짐들을 배낭에 넣을 때, 가치의 합이 최대가 되도록 짐을 고르는 방법을 찾는 알고리즘을 Knapsack Algorithm이라고 칭한다.

나는 이 문제를 보고 첫 번째로 생각한 방법은 for문을 통해 시작점에서부터 하나씩 물건을 고른 후, 나머지 것들에 대해 값을 구하는 방법을 생각했다.

그럼 처음부터 하나하나 물건을 넣어보며 가치가 최대가 되는 것을 찾을 수 있기 때문이었다.

그러나 쓸 데 없이 for문이 도는 부분이 있어 시간적으로 효율적인 코드는 아니었다.


추가 풀이

더 간단한 해결 방법

굳이 for문을 돌리지 않더라도 식 하나로도 충분히 해결 가능했다.

우선, index가 정해져 있을 때 구할 수 있는 경우의 수는 그 물건을 배낭에 담을 지, 안 담을 지와 같이 2가지 밖에 존재하지 않는다.

만약 배낭에 담는다고 가정하면 그 만큼 weight를 추가해주면 되는 것이다.

따라서 다음과 같은 점화식이 세워진다.

// stuff[2][100] = { { weight, value }, ... }
ret = max(
	stuff[1][index] + getResult(index + 1, weight + stuff[0][index]),
	getResult(index + 1, weight)
)

아래는 추가 풀이 방법으로 바꾼 코드이다.

해당 방법으로 바꾼 소스 코드

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

int getResult(int index, int weight);
int cache[101][100001], stuff[2][100], n, k;

int main() {
  scanf("%d %d", &n, &k);
  fill(&cache[0][0], &cache[100][100001], -1);

  for (int i = 0; i < n; i++)
    scanf("%d %d", &stuff[0][i], &stuff[1][i]);

  printf("%d \n", getResult(0, 0));

  return 0;
}

int getResult(int index, int weight) {
  if (weight > k) return numeric_limits<int>::min();
  if (index == n) return 0;

  int &ret = cache[index][weight];
  if (ret != -1) return ret;

  return ret = max(stuff[1][index] + getResult(index + 1, weight + stuff[0][index]), getResult(index + 1, weight));
}
Prev
BOJ#1915 - 가장 큰 정사각형 Review
Next
BOJ#2225 - 합분해 Review
Developer Hyun
ⓒ Copyright