본문 바로가기

알고리즘/백준

백준 12865번 평범한 배낭 C/C++ 풀이

https://www.acmicpc.net/problem/12865

 

12865번: 평범한 배낭

첫 줄에 물품의 수 N(1 ≤ N ≤ 100)과 준서가 버틸 수 있는 무게 K(1 ≤ K ≤ 100,000)가 주어진다. 두 번째 줄부터 N개의 줄에 거쳐 각 물건의 무게 W(1 ≤ W ≤ 100,000)와 해당 물건의 가치 V(0 ≤ V ≤ 1,000)

www.acmicpc.net

가장 고전적인 DP 문제

 

예전에는 DP를 점화식으로만 이해했었는데, 2차원 배열로 이해하고 나니 더 깊은 이해를 할 수 있게 되는 것 같다.

 

https://gsmesie692.tistory.com/113

 

Dynamic Programming: 배낭 채우기 문제 (Knapsack Problem)

도둑이 보석가게에 배낭을 메고 침입했다. 배낭의 최대 용량은 W이며, 이를 초과해서 보석을 담으면 배낭이 찢어질 것이다. 각 보석들의 무게와 가격은 알고 있다. 배낭이 찢어지지 않는 선에서

gsmesie692.tistory.com

아래는 알고리즘을 설명하는 블로그 글

 

#include <cstdio>
#include <memory.h>
#include <algorithm>

using namespace std;

FILE* in = fopen("input.txt", "r");

int n, k;
int weight[101];
int value[101];
int cache[101][100001];

//재귀함수로 구현한 DP
int dp(int idx, int w) {
	if (idx == n)
		return 0;
	if (cache[idx][w] != -1)
		return cache[idx][w];
	if (weight[idx] + w <= k)
		return cache[idx][w] = max(dp(idx + 1, w), dp(idx + 1, w + weight[idx]) + value[idx]);
	else
		return cache[idx][w] = dp(idx + 1, w);
}

int main() {
	fscanf(in, "%d %d", &n, &k);
	for (int i = 0; i < n; i++)
	{
		fscanf(in, "%d %d", &weight[i], &value[i]);
	}
	memset(cache, -1, sizeof(cache));
	printf("%d",dp(0, 0));
	return 0;
}