Notice
Recent Posts
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
관리 메뉴

이우의 개발일지

[백준 / C++] 12865 평범한 배낭 - (1) DP 본문

Coding

[백준 / C++] 12865 평범한 배낭 - (1) DP

공대이우 2025. 1. 10. 16:36
반응형

백준 12865번 평범한 배낭 문제

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

 

문제

이 문제는 아주 평범한 배낭에 관한 문제이다.

한 달 후면 국가의 부름을 받게 되는 준서는 여행을 가려고 한다. 세상과의 단절을 슬퍼하며 최대한 즐기기 위한 여행이기 때문에, 가지고 다닐 배낭 또한 최대한 가치 있게 싸려고 한다.

준서가 여행에 필요하다고 생각하는 N개의 물건이 있다. 각 물건은 무게 W와 가치 V를 가지는데, 해당 물건을 배낭에 넣어서 가면 준서가 V만큼 즐길 수 있다. 아직 행군을 해본 적이 없는 준서는 최대 K만큼의 무게만을 넣을 수 있는 배낭만 들고 다닐 수 있다. 준서가 최대한 즐거운 여행을 하기 위해 배낭에 넣을 수 있는 물건들의 가치의 최댓값을 알려주자.

입력

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

입력으로 주어지는 모든 수는 정수이다.

출력

한 줄에 배낭에 넣을 수 있는 물건들의 가치합의 최댓값을 출력한다.

예제 입력 1 

4 7
6 13
4 8
3 6
5 12

예제 출력 1 

14

 


 

평범한 배낭 풀이

 

  • 재귀로 풀면 시간 초과가 떠서, DP로 풀어야한다.
  • 가방의 무게 K개 일 때 가치 V의 합이 최대일 때를 출력

예제에 따라 입력을 나누어보았다. 열은 무게 K, 행은 물건의 Value이다.

 

이 문제에서는 가방에 넣는 순서는 무의미하다. 결국에 K 무게까지 갔을 때의 최댓값을 따지기 때문에 점화식을 아래와 같이 세우면 된다.

 

DP[i][j] = max(DP[i-1][j], DP[i-1][j - W[i]] + V[i]);

 

여기서 i는 물건의 차례, j는 무게이다.

DP[i-1][j - W[i]] + V[i] 이렇게 설정한 이유는 현재 물건을 넣을려면 j ( 현재 무게 맥스 값) 를 넘으면 안되기 때문에 W[i]를 빼서 공간을 확보한 뒤에 물건을 넣었을 때 가치 최대값을 결정하게 되는 것이다.

 

DP[n][k]를 출력하면, 결과값이게 된다. 왜냐면 DP[n]일 때는 모든 물건을 고려한 결과이고, DP[n][k]일 때는 모든 물건을 고려하여 무게 K일 때의 가치의 최댓값을 DP로 넣어놓은 것이기 때문이다. 

 


평범한 배낭 코드

#include<iostream>

using namespace std;
int W[101];
int V[101];

int dp[101][100001] = { 0, };

int main() {
	int n, k;

	cin >> n >> k;

	for (int i = 1; i <= n; i++) {
		cin >> W[i];
		cin >> V[i];
	}

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= k; j++) {
			if (j >= W[i]) {
				dp[i][j] = max(dp[i-1][j], dp[i-1][j - W[i]] + V[i]);
			}
			else {
				
				dp[i][j] = dp[i-1][j];
			}
		}

	}
	cout << dp[n][k];

	return 0;
}

 

반응형