01背包问题【动态规划】

问题:

假设有n个物品,每个物品都是有重量的,同时每个物品也是有价值的,要求把这些物品放到一个背包中,这个背包的载重量是有限制的,怎么使得背包里面的物品总价值最大?


符号表示:

N:物品个数

W:背包载重量

w[i]:物品i的重量(1<i<=N)

v[i]:物品i的价值(1<i<=N)

c[i, j]:到物品i为止,背包重量限制为j的最优解(1<i<=N, 1<j<=W)


分析:

  1. 最优解结构:对于物品i,只有两种情况,放入或不放入。假设物品i放入了是最优解的一部分,那么我们这时候拿掉物品i,c[i-1, j-w[i]]也应该是最优解
  2. 递归定义最优解的值:
  3. 按自底向上的方式计算最优值:双重循环,i从1到N循环,j从1到W循环
  4. 由计算出的结果构造一个最优解:自顶向下,i从N到1循环,如果c[i,j]>c[i-1,j],则物品i放入背包,否则反之。
代码(c++):
#ifndef ___1package__package__
#define ___1package__package__

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Package{
public:
    void init(string dataSource);
    void print();
private:
    void compute();
    int m_nN;  // The number of object
    int m_nW;  // The max weight of package
    vector<int> m_vecWeight;  // The weight of object
    vector<int> m_vecValue;   // The value of object
    vector<vector<int> > m_vecMatrix;  // The results matrix
    
};

#endif /* defined(___1package__package__) */

//
//  package.cpp
//  01package

#include "package.h"
#include <fstream>

void Package::init(string dataSource){
    // read data from datasource
    ifstream file;
    file.open(dataSource);
    if (file.is_open()){
        string buffer;
        file>>m_nW;
        file>>m_nN;
        m_vecWeight.clear();
        m_vecWeight.push_back(0);
        m_vecValue.clear();
        m_vecValue.push_back(0);
        int w, v;
        for (int i=0; i<m_nN; ++i) {
            file>>w>>v;
            m_vecWeight.push_back(w);
            m_vecValue.push_back(v);
        }
        while(!file.eof()){
            file>>buffer;
            cout<<buffer<<endl;
        }
    }
    file.close();
    
    m_vecMatrix.clear();
    // set first row and first column to zero
    for (int i=0; i<=m_nN; ++i) {
        m_vecMatrix.push_back(vector<int>(m_nW+1, 0));
    }
    
}

void Package::print(){
    compute();
    cout<<"\n=====The Results======\n"<<"The max value: "<<m_vecMatrix[m_nN][m_nW]<<endl;
}

void Package::compute(){
    for (int i=1; i<=m_nN; ++i) {
        for (int j=1; j<=m_nW; ++j) {
            int cur_weight = m_vecWeight[i];
            if (cur_weight>j) {
                m_vecMatrix[i][j] = m_vecMatrix[i-1][j];
            } else{
                m_vecMatrix[i][j] = max<int>(m_vecMatrix[i-1][j-cur_weight]+m_vecValue[i], m_vecMatrix[i-1][j]);
            }
        }
    }
}

输入的测试数据可以参考:http://zhidao.baidu.com/question/77646243.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值