问题描述:

给定一个载重量为C的背包,同时有N个物品,其重量分别为Wi(1<=j<=n),价值为Vj(1<=j<=n)。要求:把物品装入背包,并使包内物品价值最大。


解结构分析:

由于每个物品只有一件,同时,还有具体的背包的最大容量C的限制。通过物品种类数和容量C可以描述该最优解。定义为DP[i][j](0<=i<=N,0<=j<=C),要求的是DP[N][C]。


动态规划方程:

0-1 背包_动态规划 0-1背包

当j容量装不下W[i]时,DP[i][j] = DP[i-1][j];当j容量能装下W[j]时,DP[i][j]取选择第i个物品时的最大价值DP[i-1][j-W[i]]+V[i]和不选择第i个物品时的最大价值DP[i-1][j]的较大值。


代码如下:

#include<iostream>
using namespace std;
const int MAX=200;
int main()
{
    int N;
    int W[MAX+1],V[MAX+1],C,DP[MAX+1][MAX+1];
    int i,j;
    //input
    cin>>N;
    cin>>C;
    for(i=1;i<=N;i++)
        cin>>W[i];
    for(i=1;i<=N;i++)
        cin>>V[i];
    //init
    for(i=0;i<=N;i++)
        for(j=0;j<=C;j++)         
            if(i == 0 || j == 0)
                DP[i][j] = 0;
    //DP
    for(i=1;i<=N;i++)
        for(j=1;j<=C;j++)     
            if(W[i] > j)
                DP[i][j] = DP[i-1][j];
            else
                DP[i][j] = DP[i-1][j] > DP[i-1][j-W[i]]+V[i] ? DP[i-1][j] : DP[i-1][j-W[i]]+V[i];
    //output
    cout<<DP[N][C]<<endl;
    return 0;
}