2 min read

알고리즘 배낭문제

가장 흔한 문제인 배낭문제는 다양한 문제 풀이법이 있습니다.

먼저 가장 쉽게 재귀로 풀어보겠습니다.

재귀는 내가 이재품을 살때와 안살때를 재귀함수로 구현해주면됩니다.


int ws[] = { 3,4,1,2,3 }; //무게
int ps[] = { 2,3,2,3,6 }; //가치
int max = 10;

일단 간단하게 배낭크기를 10으로 잡고 5개의 물건이 있다고 보면됩니다.

//n 현재 반복 계수
//inter 현재 무게
int fn(int n, int inter) {
	if (n >= 5)return 0;
	if (inter >= max) return 0;
	return std::max(fn(n + 1, inter), fn(n + 1, inter + ws[n]) + ps[n]);
}
int main() {

	std::cout << fn(0, 0);
}

간단한 코드는 위와같다. 하지만 위의 코드는 계산했음에도 불구하고 계산할려는 특징이 있어 메모리로 계산을 했는지 안했는지 추가해야합니다. 이를 가지치기라고 하는데 다음에 설명하고 메모리DP를 풀겠습니다.

int ws[] = { 0,3,4,1,2,3 }; //무게
int ps[] = { 0,2,3,2,3,6 }; //가치
int max = 10;
int maxIn = 6;
int ret = 0;


int main() {
	int dp[6][11]{};

	for (int i = 1; i < 6; ++i) {
		for (int j = 0; j < 11; j++) {
			if (j - ws[i] < 0)
				dp[i][j] = dp[i - 1][j];
			else {
				dp[i][j] = std::max(dp[i-1][j], dp[i-1][j - ws[i]] + ps[i]);
			}

		}
	}
	std::cout << dp[5][10];
}

dp로 답을 구하는법은 엄청 간단하다 과거의 배낭의 무게를 가져올건지 과거에 특정 무게를 뺀 값을 가져올건지를 비교하면서 마지막에는 큰값이 나오게된다.