풀이
DP
- 1번째부터 N번째까지 물품을 담을 때 담을 수 있는 최대 가치를 기록한다.
- 담을 때 이전까지 담은 물품들의 무게합들의 경우의 수에 기록된 DP(해당 무게에서의 최대 가치)를 확인한다.
- DP 값에 현재 물품의 무게를 더한 값에 있는 가치와 비교해서 큰 값을 담는다.
- DP에 있는 값 중에 가장 큰 값을 출력한다.
코드
//! 2020.03.17
// TODO BJ12865_평범한배낭
#include<cstdio>
#include<vector>
using namespace std;
const int MAX = 100050;
int N,K;
int DP[MAX];
pair <int,int> inData[105];
int getMax(int n1,int n2){
if(n1>n2) return n1;
else return n2;
}
int getResult(){
for(int i=0;i<N;i++){
int w = inData[i].first;
int v = inData[i].second;
for(int k=K;k>=0;k--){
if(DP[k]!=-1){
int nextW = k+w;
int nextV = DP[k]+v;
if(nextW<=K) DP[nextW] = getMax(DP[nextW],nextV);
}
}
}
int ret = 0;
for(int i=0;i<=K;i++) ret = getMax(ret,DP[i]);
return ret;
}
int main(){
// freopen("input.txt","r",stdin);
scanf("%d %d",&N,&K);
for(int n=0;n<N;n++){
int W,V;
scanf("%d %d",&W,&V);
inData[n] = make_pair(W,V);
}
for(int i=1;i<=K;i++) DP[i] = -1;
DP[0] = 0;
printf("%d\n",getResult());
return 0;
}
실수
이전에 담은 경우의 수들을 기록한 DP를 확인할 때 1부터 확인하면서 더한 값을 다음 DP에 메모하는 식으로 구현했었다.
그렇게 하게 되면 다음 DP값이 현재 DP값에 덮이게되고 원래 확인하려던 값이 아닌 수정된 값들이 다시 수정되게 되었다.
그래서 for loop를 가장 큰 값에서부터 줄여가면서 확인하도록 만들어 그런 경우를 없애주었다.
'SW > 알고리즘 문제풀이' 카테고리의 다른 글
모험가길드 (0) | 2021.01.24 |
---|---|
BJ11729 하노이 탑 이동 순서 (0) | 2020.03.21 |
BJ9251 LCS (0) | 2020.03.17 |
BJ2565 전깃줄 (0) | 2020.03.17 |
BJ1149 RGB거리 (0) | 2020.03.12 |
Comment