1次元配列解01リュックサック問題(各種大神の分析をまとめる)

3598 ワード

多くの筆記試験問題を経験したことがあるので、この多くの動態計画アルゴリズムを学ぶべきだと知っています.
問題の説明:
nと重量と価値がそれぞれWi,Viのものがあり、これらのものの中から総質量がCを超えないものを選び、総価値量を最大にするにはどうすればいいですか?
構想分析:
シーケンス番号
weight
value
1
2
3
4
5
6
7
8
9
10
a
2
5
0
5
5
8
8
13
13
14
16
16
b
3
3
0
1
3
8
8
9
11
11
14
14
c
5
6
0
1
1
8
8
9
9
9
14
14
d
4
8
0
1
1
8
8
9
9
9
9
9
e
2
1
0
1
1
1
1
1
1
1
1
1
この表は下から上へ左から右への順番で、e 2セルが最大許容重量2を表す場合、eアイテムのみが選択可能な場合、最大価値は1です.
c 3は最大許容重量が3であることを示し、c.d.e品のみが選択可能である場合、最大価値は1であり、dとeはいずれも3より大きいため、入れられない.
a 8の値は14ですが、どうやって手に入れますか?
01バックパックの状態変換方程式によると、f[i,j]=Max{f[i-1,j-wi]+Pi(j>=Wi)、f[i-1,j]}
f[i-1][j]はb[8]の値が11,f[i-1]、j-wiはb 6の値が9,9+5=14>11であるため、a 8の値は14となる.
原文アドレスを分析する:https://blog.csdn.net/mu399/article/details/7722810
リュックサックの容量がjの場合、すでにi個の品物が入っており、最大価値はd[i]d[j]である.
第iの物品がリュックサックよりも容量が大きい場合、置くことができないので、d[i][j]=d[[i-1][j];
第iの物品がリュックサックの容量より小さい場合、置かないと上式と同じで、置くとリュックサックの容量-第iの物品の品質は前のi-1の物品を詰めて、得られた最大の価値に第iの物品の価値を加えて、両者の大きい値が最適解であると判断します.d[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i])
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define EMPTY
#define INF -65536
const int C=10;//  capability
int n;//    
int w[15],v[15];//    ,    weight,    value
int dp[1000][C+1]={0};
int main(){
    scanf("%d ",&n);
    for(int i=1;i<=n;i++)scanf("%d",&w[i]);
    for(int i=1;i<=n;i++)scanf("%d",&v[i]);
    #ifdef EMPTY//       ,    
        for(int i=0;i<=n;i++)dp[i][0]=0;
        for(int i=0;i<=C;i++)dp[0][i]=0;
    #else//    
        dp[0][0]=0;
        for(int i=1;i<=C;i++)dp[0][i]=INF;
        for(int i=1;i<=n;i++)dp[i][0]=INF;
    #endif
     for(int i=1;i<=C;i++){
         for(int j=1;j<=n;j++){
             dp[i][j]=w[j]<=i?max(dp[i][j-1],dp[i-w[j]][j-1]+v[j]):dp[i][j-1];
         }
     }
     cout<

スペースコストが大きいから小さいまでforループを構成すれば,アイテム数−1の値を直接1次元配列で保存できる.
リュックサックの容量がjの場合、すでにi個の品物が入っており、最大価値はd[j]である.
i番目の物品がリュックサックよりも容量が大きい場合、d[j]=d[j];
第iの物品がリュックサックの容量より小さい場合、置かないと上式と同じで、置くとリュックサックの容量-第iの物品の品質は前のi-1の物品を詰めて、得られた最大の価値に第iの物品の価値を加えて、両者の大きい値が最適解であると判断します.d[j]=max(dp[j],dp[j-w[i]]+v[i])
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define EMPTY
#define INF -65536
const int C=10;//  capability
int n;//    
int w[15],v[15];//    ,    weight,    value
int dp[C+1];
int main(){
    scanf("%d ",&n);
    for(int i=1;i<=n;i++)scanf("%d",&w[i]);
    for(int i=1;i<=n;i++)scanf("%d",&v[i]);
    #ifdef EMPTY//       ,    
        for(int i=0;i<=C;i++)dp[i]=0;
    #else//    
        dp[0]=0;
        for(int i=1;i<=C;i++)dp[i]=INF;
    #endif
     for(int i=1;i<=n;i++){
         for(int j=C;j>0;j--){
             dp[j]=w[i]<=j?max(dp[j],dp[j-w[i]]+v[i]):dp[j];//    +v[i]  dp[]    
         }
     }
     cout<

コードブログアドレス:https://blog.csdn.net/stack_queue/article/details/52734100