
#include<bits/stdc++.h>
using namespace std;
int n,m,c;
int a[21];
int dp[21][1<<14][21];
int go(int bag, int jewl, int capacity){
if(bag == m) return 0;
int &ret = dp[bag][jewl][capacity];
if(ret) return ret;
// 담지 않을때
ret = max(ret, go(bag+1,jewl,c));
// 담을때
for(int i=0; i<n; i++){
bool isInBag = (1<<i) & jewl;
bool canInBag = (capacity - a[i]) >= 0;
if(!isInBag && canInBag) ret = max(ret,go(bag,jewl | (1<<i), capacity-a[i])+1);
}
return ret;
}
int main(){
cin>>n>>m>>c;
for(int i=0; i<n; i++){
cin>>a[i];
}
cout<<go(0,0,c);
}
우선 DP 배열에 어떠한 상태값이 필요할지 생각해보자.
우선 제한이 있는 값인 가방, 용량은 필요할 것이다. 그리고 비트연산자를 활용하여 탐색을 진행하며 i번째 보석을 이미 담았는지 확인하는 수 jewl (1<<14) 가 필요하다.
int dp[21][1<<14][21];
이제 탐색을 진행하며 우리는 2가지의 경우의 수를 고려해주면 된다.
ret = max(ret, go(bag+1,jewl,c));
가방에 담지 않는다면, 다음 가방으로 넘어가고, capacity(현재 담을 수 있는 용량)을 c(최대 용량)으로 갱신해준다.
for(int i=0; i<n; i++){
bool isInBag = (1<<i) & jewl;
bool canInBag = (capacity - a[i]) >= 0;
if(!isInBag && canInBag) ret = max(ret,go(bag,jewl | (1<<i), capacity-a[i])+1);
}
모든 보석을 탐색하며 2가지를 고려해주면 된다.
bool isInBag = (1<<i) & jewl;
가방에 담긴 보석인지 아닌지를 체크하기 위해 비트연산자를 활용하여 isInBag 변수에 체크한다.
bool canInBag = (capacity - a[i]) >= 0;
가방에 담을 수 있는지를 체크하기 위해 canInBag 변수에 체크한다.
if(!isInBag && canInBag) ret = max(ret,go(bag,jewl | (1<<i), capacity-a[i])+1);
두 조건을 모두 만족한다면, jewl에 새로 담는 보석을 갱신해주고, 현재용량도 갱신해준다.
그렇게 계속 탐색해나가면 최댓값을 구할 수 있다!!