배낭 크기 5000
물건크기={3000,2000,1000}
각각비용={1,2,3}
배낭을 가득 채울때 비용을 최대로 할때 그 비용은?
풀이 전략
1. 물건을 조합하는 방법에 대해 전체 탐색으로 구현하기
bagsize=5000
N=3(물건갯수)
size={3000,2000,1000}
cost={1,2,3}
--------------------------------
3000
3000,2000
3000,1000
3000,2000,1000
2000
2000,1000
1000
--------------------------------
위의 내용을 단순 for loop로 구현
index로 놓고 보면
null,null,null
[0],null,null
[0],[1],null
[0],null,[2]
[0],[1],[2]
null,[1],null
null,[1],[2]
null,null,[2]
--------------
for(i=-1;i<N;i++){
for(j=-1;j<N;j++){
for(k=-1;k<N;k++){
if( i != -1 ) add(i)
if( j != -1 ) add(j)
if( k != -1 ) add(k)
이런식으로 N개의 loop로 계산하면 쉬우나 N이 가변적이라 구현의 어려움
if( i != -1 ) add(i)
if( j != -1 ) add(j)
if( k != -1 ) add(k)
이런식으로 N개의 loop로 계산하면 쉬우나 N이 가변적이라 구현의 어려움
--------------
다른 방법으로 tree형태로 고민해볼 수 있다.
즉 처음 index 0을 선택하느냐 안하느냐에 따라 2가지가 나뉘고
그후 index 1을 선택하느냐 안하느냐에 따라 2가지가 나뉜다. (0 미선택 1 선택)
1 0 index 0
1 0 1 0 index 1
1 0 1 0 1 0 1 0 index 2
이것을 순회하는 방법은 DFS,BFS가 있습니다.
깊이 우선인 DFS는 스택으로 구현이 됩니다.
소스는 이렇게 되며, 순수하게 조합하는 방법에 대한 소스 입니다.
#include <stdio.h> #define N 3 int bag[N]={-1}; int size[N]={5000,3000,1000}; int DFS(int level,int item) { if(level>=0) { if( item == 0) bag[level]=-1; else bag[level]=size[level]; } if(level >= N-1) { int i; for(i=0;i<N;i++){ printf("%d ",bag[i]); } printf("\n"); return 0; } DFS(level+1,0); DFS(level+1,1); return 0; } int main(void) { DFS(-1,0); return 0; }
실행 결과
-1 -1 -1 -1 -1 1000 -1 3000 -1 -1 3000 1000 5000 -1 -1 5000 -1 1000 5000 3000 -1 5000 3000 1000
2. 그 중에 배낭크기 보다 커진다면 중단
마지막 노드에서 배낭크기의 합을 출력하도록 한다.
#include <stdio.h> #define N 3 int bagsize=5000; int bag[N]={-1}; int size[N]={5000,3000,1000}; int DFS(int level,int item,int sum) { if(level>=0) { if( item == 0){ bag[level]=-1; } else { bag[level]=size[level]; sum+=size[level]; } } if(level >= N-1) { int i; for(i=0;i<N;i++){ printf("%d ",bag[i]); } printf("sum %d\n",sum); return 0; } DFS(level+1,0,sum); DFS(level+1,1,sum); return 0; } int main(void) { DFS(-1,0,0); return 0; }
실행화면
Success time: 0 memory: 2160 signal:0
-1 -1 -1 sum 0 -1 -1 1000 sum 1000 -1 3000 -1 sum 3000 -1 3000 1000 sum 4000 5000 -1 -1 sum 5000 5000 -1 1000 sum 6000 5000 3000 -1 sum 8000 5000 3000 1000 sum 9000
미리 DFS탐색을 중지하고 다음 탐색을 하기위해서는 중간마다 총수치를 계산해야 한다.
bagsize < sum+size[level] 조건을 추가하였다. 이번에 추가되는 크기가 커진다면 level을 더 진입 하지 않도록 한다.
#include <stdio.h> #define N 3 int bagsize=5000; int bag[N]={-1}; int size[N]={5000,3000,1000}; int DFS(int level,int item,int sum) { if(level>=0) { if(item == 0){ bag[level]=-1; } else { #if 1 if( bagsize < sum+size[level] ) { int i; for(i=0;i<level;i++){ printf("%d ",bag[i]); } printf("sum %d\n",sum); return 0; } #endif bag[level]=size[level]; sum+=size[level]; } } if(level >= N-1) { int i; for(i=0;i<N;i++){ printf("%d ",bag[i]); } printf("sum %d\n",sum); return 0; } DFS(level+1,0,sum); DFS(level+1,1,sum); return 0; } int main(void) { DFS(-1,0,0); return 0; }
Success time: 0 memory: 2160 signal:0
-1 -1 -1 sum 0 -1 -1 1000 sum 1000 -1 3000 -1 sum 3000 -1 3000 1000 sum 4000 5000 -1 -1 sum 5000 5000 -1 sum 5000 5000 sum 5000
3. 비용도 고려하기
sum 계산하는 위치에 cost계산도 같이 하면 쉽게 처리할 수 있다.
#include <stdio.h> #define N 3 int bagsize=5000; int bag[N]={-1}; int size[N]={5000,3000,1000}; int cost[N]={3,2,1}; int maxcost = 0; int DFS(int level,int item,int sum,int sumcost) { if(level>=0) { if(item == 0){ bag[level]=-1; } else { if( bagsize < sum+size[level] ) { int i; for(i=0;i<level;i++){ printf("%5d ",bag[i]); } printf("/sum %5d costsum %5d costmax %5d\n",sum,sumcost,maxcost); return 0; } bag[level]=size[level]; sum+=size[level]; sumcost+=cost[level]; if( maxcost < sumcost ) maxcost = sumcost; } } if(level >= N-1) { int i; for(i=0;i<N;i++){ printf("%5d ",bag[i]); } printf("sum %5d costsum %5d costmax %5d\n",sum,sumcost,maxcost); return 0; } DFS(level+1,0,sum,sumcost); DFS(level+1,1,sum,sumcost); return 0; } int main(void) { DFS(-1,0,0,0); return 0; }
-1 -1 -1 sum 0 costsum 0 costmax 0 -1 -1 1000 sum 1000 costsum 1 costmax 1 -1 3000 -1 sum 3000 costsum 2 costmax 2 -1 3000 1000 sum 4000 costsum 3 costmax 3 5000 -1 -1 sum 5000 costsum 3 costmax 3 5000 -1 /sum 5000 costsum 3 costmax 3 5000 /sum 5000 costsum 3 costmax 3
댓글 없음:
댓글 쓰기