12920번: 평범한 배낭 2
첫 번째 줄에 N, M (1 ≤ N ≤ 100, 1 ≤ M ≤ 10,000) 이 빈칸을 구분으로 주어진다. N은 민호의 집에 있는 물건의 종류의 수이고 M은 민호가 들 수 있는 가방의 최대 무게다. 두 번째 줄부터 N개의 줄에
www.acmicpc.net
시간제한: 1초
메모리제한: 512MB
1) 덱을 이용한 DP, 2) 물건의 개수를 2의 지수꼴로 분할해 푸는 것이 일반적인 방법으로 보인다.
그러나 이 두 방법을 사용하지 않고 단순한 배낭문제 아이디어로 O(N2M) 만에 풀 수 있다.
N=100,M=10000 이라고 했을 때 연산 횟수가 약 1억회이고,
아래 코드를 제출하면 약 12ms에 통과한다.
<소스 코드>
#include <cstdio>
int main() {
int n,m;
scanf("%d %d", &n, &m);
int weight[n], value[n], iscontain[m+1][n], maxvalue[m+1];
for (int i = 0; i < n; i++) {
scanf("%d %d %d", &weight[i], &value[i], &iscontain[0][i]);
for (int j = 1; j < m+1; j++) {
iscontain[j][i] = iscontain[0][i];
}
}
// O(n*n*m)
for (int i = 0; i < m+1; i++) {
maxvalue[i] = 0;
for (int j = 0; j < n; j++) {
if (i-weight[j] >= 0) {
if (maxvalue[i] < maxvalue[i-weight[j]] + value[j] && iscontain[i-weight[j]][j] != 0) {
maxvalue[i] = maxvalue[i-weight[j]] + value[j];
for (int p = 0; p < n; p++) {
iscontain[i][p] = iscontain[i-weight[j]][p];
}
iscontain[i][j]--;
}
}
}
}
int max = 0;
for (int i = 0; i < m+1; i++) {
if (maxvalue[i] > max) max = maxvalue[i];
}
printf("%d", max);
}
<코드 설명>
iscontain[m+1][n] : 배낭 무게가 0≤x≤m일 때 그 배낭에 더 넣을 수 있는 물건 개수를 저장하는 배열
maxvalue[m+1] : m만큼 돌면서, 배낭의 무게가 0≤x≤m일 때 value의 최고값을 저장하는 배열
이런 식으로 N2M 만큼 돌고 마지막에 maxvalue 배열에서 가장 큰 값을 찾으면 그것이 정답이 된다.
'BOJ' 카테고리의 다른 글
[백준 1078] 뒤집음 (0) | 2022.06.27 |
---|---|
[백준 22021] 자동분무기 (0) | 2022.06.26 |
[백준 9661] 돌 게임7 (1) | 2022.06.22 |
[백준 1007] 벡터 매칭 - 백트래킹 (0) | 2022.06.20 |
[백준 20149] 선분 교차 3 (0) | 2022.06.18 |