/**
* knapsack problem(Memoization)
*/
//Reconstruction 함수에서 cache 만으로 해결할 경우 마지막 선택 아이템을 놓칠 수 있다.
typedef struct _stuff{
char name[20];
short size;
short need;
}stuff;
stuff items[100];
int cache[1000][100];
int mystrlen(const char* str){int len=0;for(;str[len]!='\0';len++){} return len;}
void set_str(char* str, const char* new_string, int n){
int i=0;for(;i<=n;i++){str[i] = new_string[i];}
}
//지금까지 고른 물건들의 목록이 items 에 주어질때,
//남은 용량을 채워 얻을 수 있는 최대의 절박도 합.
//=> 완전 검색을 하기 때문에 순서와 상관없이 넣으면 되고 적어도 지금까지 고려된 것 과
// 고려 되지 않은 것은 구별 할 수 있는 숫자이길 원하므로 인덱스 순서로 탐색.
int pack(int capacity, int i){
int selected = -1;
int unselected = -1;
//기저 사례
if(i==6){
return 0;
}
//캐쉬 확인
if(cache[capacity][i]!=-1){
return cache[capacity][i];
}
if(capacity - items[i].size >= 0){
selected = pack(capacity - items[i].size,i+1) +items[i].need;
}
unselected = pack(capacity, i+1);
if(selected > unselected){
cache[capacity][i] = selected;
}else{
cache[capacity][i] = unselected;
}
return cache[capacity][i];
}
int selectedNumber[100];
int selectedN;
void reconstruct(int capacity, int item){
if(item==6) return;
if(pack(capacity,item) == pack(capacity,item+1)){
reconstruct(capacity,item+1);
}else{
selectedNumber[selectedN] = item;
selectedN++;
reconstruct(capacity-items[item].size,item+1);
}
}
int main(){
int n=6;
int w=10;
int i,j;
for(i=0;i<1000;i++){
for(j=0;j<100;j++){
cache[i][j] = -1;
}
}
set_str(items[4].name, "laptop", mystrlen("laptop"));
items[4].size = 4;
items[4].need = 7;
set_str(items[0].name, "camera", mystrlen("camera"));
items[0].size = 2;
items[0].need = 10;
set_str(items[2].name, "xbox", mystrlen("xbox"));
items[2].size = 6;
it\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0ems[2].need = 6;
set_str(items[3].name, "grinder", mystrlen("grinder"));
items[3].size = 4;
items[3].need = 7;
set_str(items[1].name, "dumbell", mystrlen("dumbell"));
items[1].size = 2;
items[1].need = 5;
set_str(items[5].name, "encyclopedia", mystrlen("encyclopedia"));
items[5].size = 10;
items[5].need = 4;
selectedN =0;
reconstruct(w, 0);
printf("%d %d
",pack(w,0),selectedN);
for(int i=0;i<selectedN;i++){
printf("%s
",items[selectedNumber[i]].name);
}
}