0/1背包问题-动态规划法

版权声明:转载必须注明出处,违者必究。 https://blog.csdn.net/qq_41856518/article/details/84331323

0/1背包问题:给定n种物品和一个背包,物品i(1<<i<<n)的重量是w[i],价值是v[i],背包容量为C,对每种物品有两种选择:装入背包或不装入背包。如何选择装入背包的物品,使得装入背包中物品的总价值最大。

分析:

     用动态规划法考虑原问题的一部分,设value(i,j)表示将前i个物品装入容量为j的背包获得的最大价值,在决策x[i]时,已确定了(x[1],.........x[i-1]),则问题处于以下两种状态之一:(1)背包容量不足以装入物品i,则装入前i个物品的到的最大价值和装入前i-1个物品的价值相等,即x[i]=0,背包不增加价值。    ( 2)背包容量可以装入物品i,如果把物品i装入背包,则背包中物品的价值等于把前i-1个物品装入容量为j-w[i]的背包中的价值加上第i个物品的价值v[i];如果第i个物品没有装入背包,则背包中的价值等于把前i-1个物品装入容量为j的背包中所取的价值。显然,取两者中较大值作为把前i个物品装入容量为j的背包中的最优解。

      为确定装入背包的具体物品,从value(n,c)的值向前推,如果v(n,c)>v(n-1,c),表明第n个物品被装入背包,前n-1个物品被装入容量为c-w[i]的背包中;否则,第n个物品没有被装入背包中,前n-1个物品被装入容量为c的背包中,依次类推,直到确定第1个物品是否被装入背包中为止。

代码中打印了求解的具体过程:

#include<iostream>
#include<math.h>
const int maxsize=10;
using namespace std;
int snackbag(int n,int c,int w[],int v[])
{
    int i,j;
    int value[100][100],x[maxsize];
    for(i=0;i<=n;i++)
        value[i][0]=0;
    for(j=0;j<=c;j++)
        value[0][j]=0;
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=c;j++)
        {
            if(j<w[i]){value[i][j]=value[i-1][j];}
            else {value[i][j]=max(value[i-1][j], value[i-1][j-w[i]]+v[i]);}
        }
    }
    for(j=c,i=n;i>0;i--)
    {
        if(value[i][j]>value[i-1][j])
        {
            x[i]=1;j=j-w[i];
        }
        else {x[i]=0;}
    }
    for(i=0;i<=n;i++)
    {
        for(j=0;j<=c;j++)
        {
         cout<<value[i][j]<<" ";
        }
        cout<<endl;
    }
    return value[n][c];
}
int main()
{
    int n,c,v[maxsize+1],w[maxsize+1];
    cin>>n>>c;
    for(int i=1;i<=n;i++)
        cin>>w[i];
    for(int i=1;i<=n;i++)
        cin>>v[i];
    int maxvalue=snackbag(n,c,w,v);
    cout<<endl;
    cout<<"最大价值为:"<<maxvalue<<endl;
}

运行结果:

第三行到第八行是求解的具体过程

猜你喜欢

转载自blog.csdn.net/qq_41856518/article/details/84331323