0-1バックパック問題とダイナミックプランニングのC/C++コード

4331 ワード

ブログの参照https://blog.csdn.net/stpeace/article/details/46700657
0-1リュックサックの問題:泥棒が出てきて活動して、リュックサックを持ってきて、せいぜい50斤のものを入れることができる小さな袋を持っています.彼の目が明るくなると、3つの宝物a,b,c.を見つけた.そのうちaは重さ10斤で、価値は60元だった.b重さは20斤で、価値は100元です.c重さは30斤で、価値は120元です.質問:リュックサックの許容範囲内で、泥棒は最大いくらまで盗むことができますか?
プッシュ式を書こうと思っていたのですが、このCSDNは書くのが不便なのでやめました.プッシュ式があれば、値を計算するには、コンピュータの長い項目であり、コードを直接与えましょう.コードにはすべてが含まれています(50斤=5十斤、10斤を単位とし、プログラミングが便利です):
#include
using namespace std;

#define N 8 // N   
#define V 10 // C     capacity

int main()
{
    int value[N + 1] = { 0, 120, 100, 60, 100, 160, 180, 20, 5 }; //   
    int weight[N + 1] = { 0, 3,  2,  1, 5, 4, 3, 3, 2 };    //   
    int f[N + 1][V + 1] = { 0 }; // f[i][j]        j    ,  i        

    int i = 1;
    int j = 1;
    for (i = 1; i <= N; i++)
    {
        for (j = 1; j <= V; j++)
        {
            //        
            if ( j < weight[i] )  //j - weight[i]
            {
                f[i][j] = f[i - 1][j];
            }
            else
            {
                int x = f[i - 1][j];
                int y = f[i - 1][j - weight[i]] + value[i];
                f[i][j] = x < y ? y : x;
            }
        }
    }

    for (i = N; i >= 1; i--)
    {
        for (j = 1; j <= V; j++)
        {
            printf("%4d ", f[i][j]);
        }

        cout << endl;
    }


    getchar();
    return 0;
}

jは何を表しますか.(便利配列で使用される数for(j=1;j<=V;j++))weight[i]0,1,2,3は上記のように↓f[i][j]の意味if(j0 int x=f[i-1][j];前輪容量およびパッケージ内価値は、前輪価値int y=f[i-1][j-weight[i]+value[i];j=weightの場合、vaule[i]、j>weightの場合、前輪容量およびパッケージ内価値は前輪価値+value[i]の2つの意味↓このときf[i][j]の値更新の意味はxとyを比較することによって現在の最適化を得る!
数式を渡す思想は数列で、a 1、a 2、a 3、、、anから、だからやっとこのような情況があります
前輪の意味は、i=1(1つの物品のみを持ち、weight配列とvalue配列の最初の要素の値)、i=2(2つの物品のみを持ち、weight配列とvalue配列の最初の要素の値と2番目の要素の値)現在持っている容量と重量の差<0の場合、f[i][j]=f[i-1][j]を通過する.ホイールを取得するには、現在の容量と重量の差>=0がint x=f[i-1][j]である場合に最適である.int y = f[i - 1][j - weight[i]] + value[i]; 現在の最適化を取得!