0 - 1 가방 문제

60745 단어 문제 집
0 - 1 가방 문제: n 가지 물품 과 용량 이 C 인 가방 을 정 하고 물품 i 의 무 게 는 wi 이 며 그 가 치 는 vi 이다.
― 가방 에 들 어 가 는 아 이 템 을 어떻게 선택해 야 가방 에 들 어 가 는 아 이 템 의 총 가치 가 가장 큽 니까?
한 파 를 분석 하면 모든 물품 에 대해 우 리 는 두 가지 선택 을 선택 하거나 가 져 오지 않 을 뿐 특정한 물품 의 일부분 을 선택 할 수 없고 같은 물품 을 여러 번 불 러 올 수 없다.
해결 방법: 크기 를 설명 합 니 다. m [n] [c] 의 2 차원 배열, m [i] [j] 는 제 i 물품 을 직면 하고 있 으 며 가방 용량 은? j 시 얻 을 수 있 는 최대 가치 ,그러면 우 리 는 m [i] [j] 의 계산 방법 을 쉽게 분석 할 수 있다.
(1). j < w [i] 의 경우 가방 용량 이 부족 하여 제 i 아 이 템 을 내 려 놓 을 수 있 습 니 다. 가지 지 않 기로 선택 할 수 밖 에 없습니다.
m[ i ][ j ] = m[ i-1 ][ j ]
(2). j > = w [i] 의 경우 가방 용량 이 i 번 째 아 이 템 을 내 려 놓 을 수 있 습 니 다. 이 아 이 템 을 가지 고 더 큰 가 치 를 얻 을 수 있 는 지 고려 해 야 합 니 다.
가 져 가면 m [i] [j] = m [i - 1] [j - w [i] + v [i].여기 m [i - 1] [j - w [i] 는 i - 1 개의 아 이 템 을 고려 한 것 으로 가방 용량 이 j - w [i] 일 때의 최대 가치 이자 i 번 째 아 이 템 에 w [i] 의 공간 을 비 운 셈 이다.
안 들 면 m [i] [j] = m [i - 1] [j], 동일 (1)
가 져 갈 지 말 지 는 당연히 이 두 가지 상황 을 비교 하 는 것 이 가장 가치 가 있다.
이로부터 상태 전이 방정식 을 얻 을 수 있다.

   
   
   
   
  1. if(j>=w[i])
  2. m[i][j]=max(m[i -1][j],m[i -1][j-w[i]]+v[i]);
  3. else
  4. m[i][j]=m[i -1][j];


:0-1 。 0-1 , m[i][j] j, i、i+1、……、n 0-1 。

v = {8, 10, 6, 3, 7, 2},

w = {4, 6, 2, 2, 5, 1},

C = 12 m[i][j] 。

0 1 2 3 4 5 6 7 8 9 10 11 12
1 0 0 0 8 8 8 8 8 8 8 8 8
2 0 0 0 8 8 10 10 10 10 18 18 18
3 0 6 6 8 8 14 14 16 16 18 18 24
4 0 6 6 9 9 14 14 17 17 19 19 24
5 0 6 6 9 9 14 14 17 17 19 21 24
6 2 6 8 9 11 14 16 17 19 19 21 24
( , 0)
m[2][6], , 6 , 8, , , , 10, 。m[2][6]=m[1][0]+10=0+10=10; , m[6][12] , C 。

   
   
   
   
  1. #include
  2. #include
  3. using namespace std;
  4. const int N= 15;
  5. int main()
  6. {
  7.     int v[N]={ 0, 8, 10, 6, 3, 7, 2};
  8.     int w[N]={ 0, 4, 6, 2, 2, 5, 1};
  9.     int m[N][N];
  10.     int n= 6,c= 12;
  11.     memset(m, 0, sizeof(m));
  12.     for( int i= 1;i<=n;i++)
  13.     {
  14.         for( int j= 1;j<=c;j++)
  15.         {
  16.             if(j>=w[i])
  17.                 m[i][j]=max(m[i -1][j],m[i -1][j-w[i]]+v[i]);
  18.             else
  19.                 m[i][j]=m[i -1][j];
  20.         }
  21.     }
  22.     for( int i= 1;i<=n;i++)
  23.     {
  24.         for( int j= 1;j<=c;j++)
  25.         {
  26.             cout<' ';
  27.         }
  28.         cout<< endl;
  29.     }
  30.     return 0;
  31. }

, , 。

x[ ] ,x[i]=0 ,x[i]=1 。

m[n][c] , m[n][c]=m[n-1][c] , n , x[n]=0 ; x[n]=1。 x[n]=0 , x[n-1][c] ; x[n]=1 , x[n-1][c-w[i]] 。 , 。( , 。。)


   
   
   
   
  1. void traceback()
  2. {
  3. for( int i=n;i> 1;i--)
  4. {
  5. if(m[i][c]==m[i -1][c])
  6. x[i]= 0;
  7. else
  8. {
  9. x[i]= 1;
  10. c-=w[i];
  11. }
  12. }
  13. x[ 1]=(m[ 1][c]> 0)? 1: 0;
  14. }

A、B、C、D , Wk Vk , 30 , ?

Project

Wk

Vk

A

15

12

B

10

8

C

12

9

D

8

5


   
   
   
   
  1. #include
  2. #include
  3. using namespace std;
  4. const int N= 150;
  5. int v[N]={ 0, 12, 8, 9, 5};
  6. int w[N]={ 0, 15, 10, 12, 8};
  7. int x[N];
  8. int m[N][N];
  9. int c= 30;
  10. int n= 4;
  11. void traceback()
  12. {
  13. for( int i=n;i> 1;i--)
  14. {
  15. if(m[i][c]==m[i -1][c])
  16. x[i]= 0;
  17. else
  18. {
  19. x[i]= 1;
  20. c-=w[i];
  21. }
  22. }
  23. x[ 1]=(m[ 1][c]> 0)? 1: 0;
  24. }
  25. int main()
  26. {
  27. memset(m, 0, sizeof(m));
  28. for( int i= 1;i<=n;i++)
  29. {
  30. for( int j= 1;j<=c;j++)
  31. {
  32. if(j>=w[i])
  33. m[i][j]=max(m[i -1][j],m[i -1][j-w[i]]+v[i]);
  34. else
  35. m[i][j]=m[i -1][j];
  36. }
  37. } /*
  38. for(int i=1;i<=6;i++)
  39. {
  40. for(int j=1;j<=c;j++)
  41. {
  42. cout<
  43. }
  44. cout<
  45. }
  46. */
  47. traceback();
  48. for( int i= 1;i<=n;i++)
  49. cout<
  50. return 0;
  51. }

  52. x[i] :0111, m[4][30]:22。

    : BCD , 22 。


    , 。


좋은 웹페이지 즐겨찾기