动态规划之0-1背包问题

  1. 问题描述
    0−1背包问题是应用动态规划设计求解的典型例题
    已知n种物品和一个可容纳c重量的背包,物品i的重量为w[i],产生的效益为p[i]。在装包时物品i可以装入,也可以不装,但不可拆开装。
    问如何装包,所得装包总效益最大。
  2. 算法分析
    最优子结构特性
    0−1背包的最优解具有最优子结构特性。
    与一般背包问题不同,0−1背包问题要求 即物品i不能折开,或者整体装入,或者不装。当约定每件物品的重量与效益均为整数时,可用动态规划求解。
    按每一件物品装包为一个阶段,共分为n个阶段
    1、建立递推关系(先看最后一个装不装)
    设g(i,j)为背包容量j,i可取物品范围为:1,2,…,i的最大效益值。
    (1)则当0≤j<w(i)时,物品i不可能装入。最大效益值与g(i−1,j)相同。
    (2)而当j≥w(i)时,有两种选择
    不装入物品i,这时最大效益值为g(i−1,j);
    装入物品i,这时已产生效益p(i),背包剩余容积j−w(i)可以选择物品1,2,…,i−1来装,最大效益值为g(i−1,j−w(i))+p(i)。期望的最大效益值是两者中的最大者。
    于是有递推关系
    这里写图片描述
    其中w(i),p(i)均为正整数,x(i)∈{0,1}, i=1,2,…,n。
    边界条件为:
    g(1, j)=p(1), 当j≥w(1);
    g(1, j)=0, 当j
#include <iostream>
#define N 50

using namespace std;

int main()
{
    int weight[N];
    int power[N];
    int dp[N][5*N]; 
    int n, capacity;

    cout << "please input the number of goods and the package's capacity" << endl; 
    cin >> n >> capacity;
    cout << "please input every goods's weight and power" << endl; 
    for (int i=1; i<=n; ++i)
    {
        cin >> weight[i] >> power[i]; 
    }

    //初始化边界条件
    for (int i=1; i<=capacity; ++i)
    {
        if (i >= weight[1])
            dp[1][i] = power[i];
        else
            dp[1][i] = 0; 
    }

    //顺推计算i是物品个数 
    for (int i=2; i<=n; ++i)
    {
        //背包剩余重量 
        for (int j=1; j<=capacity; ++j)
        {
            //装不下
            if (weight[i] > j)
                dp[i][j] = dp[i-1][j];
            else    //可以装下
                dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]]+power[i]); 
        }
    }
    cout << "the most power is: ";
    cout << dp[n][capacity] << endl; 

    return 0;
}

你可能感兴趣的:(算法,动态规划)