[백준] 12865번 평범한 배낭 (= plain backpack) - 재우스 프로그래밍 (C 언어)
2021. 1. 30. 08:47ㆍ백준
문제 링크 : www.acmicpc.net/problem/12865
#include <stdio.h>
#include <stdlib.h>
#define DEBUG 0
#define MAX_OBJECT_COUNT 100
#define MAX_WEIGHT_BAG 100000
typedef struct _Node {
int mWeight;
int mValue;
} Node;
//input 물품과 무게를 저장하는 배열
Node arrInput[MAX_OBJECT_COUNT + 1];
//arrInput에서 가지고 갈 수 있는 물건의 조합으로 가장 큰 value값
int DPmap[MAX_OBJECT_COUNT + 1][MAX_WEIGHT_BAG];
//N : 물품의 수량, K : 배낭이 버틸 수 있는 최대 무게
int N, K;
//Brute Force 알고리즘으로도 해결이 가능하나 시간 부족 발생
/*
//arrInput에 저장된 순서대로 물품을 넣을 수 있는 모든 방식을 넣어보고 최댓값을 계속 갱신하는 함수
//인자 Node: 현재 무게와 가치 상황이 저장된 Node
//인자 int: 함수 내에서 배낭에 넣을지 말지 고민할 무게, 가치의 index
void weightBruteForce(Node *, int);
void sortArrInput(void);
*/
//Dynamic Programming 알고리즘으로 N, K까지 DPmap을 채움
void DP(void);
int main(void)
{
//arrInput의 index
//int arrInputIdx = 0;
//지속적으로 배낭 상황을 저장할 현재 Node
Node *currentNode;
currentNode = (Node *)malloc(sizeof(Node));
currentNode->mWeight = 0;
currentNode->mValue = 0;
//input 저장하기
scanf("%d %d", &N, &K);
for (int i = 1; i <= N; i++) {
scanf("%d %d", &arrInput[i].mWeight, &arrInput[i].mValue);
}
//Brute Force 방법으로 풀 때
/*
//arrInput 오름차순으로 정렬
sortArrInput();
//가방에 넣을 수 있는 모든 경우의 수 탐색하기
for (int i = 0; i < N; i++) {
weightBruteForce(currentNode, i);
}
printf("%d\n", result);
*/
DP();
printf("%d\n", DPmap[N][K]);
free(currentNode);
return 0;
}
void DP(void)
{
for (int i = 0; i <= N; i++) {
for (int j = 0;j <= K; j++) {
#if DEBUG
if (i > 0 && j > 0 && j - arrInput[i - 1].mWeight > 0 && j == 100000) {
printf("i: %d, j: %d\n", i, j);
printf("map[%d][%d]: %d\n", i - 1, j, DPmap[i - 1][j]);
printf("map[%d][%d]: %d\n", i - 1, j - arrInput[i - 1].mWeight, DPmap[i - 1][j - arrInput[i - 1].mWeight]);
printf("value: %d\n", arrInput[i - 1].mValue);
}
#endif
//물건이 0개이거나 가방 허용 무게가 0이면 아무것도 넣을 수 없음.
if (i == 0 || j == 0) {
DPmap[i][j] = 0;
continue;
}
//새로 추가되는 물건의 무게가 현재 배낭 최대 무게보다 무거우면 새로 추가되는 물건은 절대 포함 될 수 없음.
if (arrInput[i].mWeight > j) {
DPmap[i][j] = DPmap[i - 1][j];
}
//새로 추가되는 물건의 무게가 현재 배낭 최대 무게는 넘지 않을 때
else {
//새로 추가되는 물건이 포함되지 않으면 value가 더 클 때
if (DPmap[i - 1][j] > DPmap[i - 1][j - arrInput[i].mWeight] + arrInput[i].mValue) {
DPmap[i][j] = DPmap[i - 1][j];
}
//새로 추가되는 물건이 포함되면 value가 더 클 때
else {
DPmap[i][j] = DPmap[i - 1][j - arrInput[i].mWeight] + arrInput[i].mValue;
}
}
}
}
return;
}
/*
void weightBruteForce(Node *currentNode, int arrInputIdx)
{
//현재 무게에서 인자의 무게까지 추가되면 배낭의 한계를 초과할 때
if (currentNode->mWeight + arrInput[arrInputIdx].mWeight > K) {
return;
}
//현재 무게, 가치 갱신
currentNode->mWeight += arrInput[arrInputIdx].mWeight;
currentNode->mValue += arrInput[arrInputIdx].mValue;
#if DEBUG
printf("current W: %d, V: %d\n", currentNode->mWeight, currentNode->mValue);
printf("result: %d, current idx: %d\n", result, arrInputIdx);
printf("\n");
#endif
//갱신된 현재 가치가 최대치라면 result 갱신
if (result < currentNode->mValue) {
result = currentNode->mValue;
}
//배열 순서대로 탐색
for (int i = arrInputIdx + 1; i < N; i++) {
if (currentNode->mWeight + arrInput[arrInputIdx + 1].mWeight > K) {
break;
}
weightBruteForce(currentNode, i);
}
//현재 무게, 가치 backtracking
currentNode->mWeight -= arrInput[arrInputIdx].mWeight;
currentNode->mValue -= arrInput[arrInputIdx].mValue;
return;
}
void sortArrInput(void)
{
int tempWeight = 0, tempValue = 0;
//배열의 맨 뒤부터 정렬이 되므로 0부터 i-1까지 정렬을 반복한다.
for (int i = N; i > 0; i--) {
for (int j = 0; j < i - 1; j++) {
//앞에 있는 무게가 더 크면 swap 해준다.
if (arrInput[j].mWeight > arrInput[j + 1].mWeight) {
tempWeight = arrInput[j].mWeight;
tempValue = arrInput[j].mValue;
arrInput[j].mWeight = arrInput[j + 1].mWeight;
arrInput[j].mValue = arrInput[j + 1].mValue;
arrInput[j + 1].mWeight = tempWeight;
arrInput[j + 1].mValue = tempValue;
}
}
}
return;
}
*/
'백준' 카테고리의 다른 글
[백준] 2504번 괄호의 값 (= value of parentheses) - 재우스 프로그래밍 (C 언어) (0) | 2021.01.31 |
---|---|
[백준] 4949번 균형잡힌 세상 (= balanced world) - 재우스 프로그래밍 (C 언어) (0) | 2021.01.30 |
[백준] 15954번 인형들 (= dolls) - 재우스 프로그래밍 (C 언어) (0) | 2021.01.30 |
[백준] 1967번 트리의 지름 (= tree diameter) - 재우스 프로그래밍 (C 언어) (0) | 2021.01.29 |
[백준] 1062번 가르침 (= teaching) - 재우스 프로그래밍 (C 언어) (0) | 2021.01.29 |