0-1背包问题(c/c++)

原创 2016年08月28日 22:00:59

问题介绍:现在有一个可以载重w的背包和n个物品,每个物品的重量和价格分别为wivi,请选择所装物品,使得在不超过背包载重的前提下,背包里的物品价格最高。

求解方案1:

#include<iostream>
#include<vector>
using namespace std;
/*
w  背包最大载重
n  物品总数
ws 物品重量
vs 物品价值
res[i][j] 表示针对前i个物品,当背包的最大载重为j时,能放物品的最大价值
choice[i] =0表示第i个物品不选择
*/
int main()
{
    int w, n;
    cin >> w >> n;
    vector<int> ws;
    vector<int> vs;
    for (int i = 0; i < n; i++)
    {
        int tmpW, tmpV;
        cin >> tmpW >> tmpV;
        ws.push_back(tmpW);
        vs.push_back(tmpV);
    }
    vector<int> choice(n + 1, 0);
    int** res = new int* [n + 1];
    for (int i = 0; i <= n; i++)
    {
        res[i] = new int[w + 1];
    }
    //遍历所有的物品
    for (int i = 0; i <= n; i++)
    {
        for (int j = 0; j <= w; j++)
        {
            if (i == 0 || j == 0)
            {
                res[i][j] = 0;
            }
            else
            {
                if (j >= ws[i - 1]) //如果当前背包可以存放第i个物品
                {
                    //res[i][j]:对于前i个物品,当背包容量为j时的最大价值
                    //res[i-1][j],对于前(i-1)个物品,背包容量为j时的最大价值
                    //res[i-1][j-ws[i]],对于前(i-1)个物品,背包容量为j-ws[i-1]时的最大价值
                    res[i][j] = max(res[i - 1][j], res[i - 1][j - ws[i - 1]] + vs[i - 1]);
                }
                else
                {
                    res[i][j] = res[i - 1][j];
                }
            }
        }
    }
    int maxValue = res[n][w];
    int maxWeight = w;
    //输出选择方案
    while (maxValue)
    {
        for (int i = 1; i <= n; i++)
        {
            if (maxWeight >= ws[i - 1]
                    && (maxValue - res[n][maxWeight - ws[i - 1]]) == vs[i - 1])
            {
                choice[i] = 1;
                maxValue -= vs[i - 1];
                maxWeight -= ws[i - 1];
            }
        }
    }
    cout << "最优方案:" << endl;
    for (int i = 1; i <= n; i++)
    {
        if (choice[i] == 1)
        {
            cout << "选择物品:" << i << ",价格:" << vs[i - 1] << ",重量:" <<
                 ws[i - 1] << endl;
        }
    }
    cout << "The max value is " << res[n][w] << endl;
    for (int i = 0; i <= n; i++)
    {
        delete[] res[i];
    }
    return 0;
}

求解方案2:

#include<iostream>
#include<vector>
using namespace std;
/*
w  背包最大载重
n  物品总数
ws 物品重量
vs 物品价值
res[j] 表示当背包的最大载重为j时,能放物品的最大价值
*/
int main()
{
    int w, n;
    vector<int> ws;
    vector<int> vs;
    vector<int> res(w + 1, 0);
    for (int i = 0; i < n; i++)
    {
        int tmpW, tmpV;
        cin >> tmpW >> tmpV;
        ws.push_back(tmpW);
        vs.push_back(tmpV);
    }
    //这里的i是代表前i个物品子集
    for (int i = 0; i < n; i++)
    {
        //这里为什么需要从w开始递减遍历?
        //仔细分析解决方案1可以发现,最后计算最大价值或者求解最优解决方案,都只用了res[n][:]这个维度的值。
        //所不同的是,解决方案1保留了所有历史信息,解决方案2是只保留上一次的历史信息,同时我们发现
        //res[j]的更新只会用到res[i](i<j)的历史数据,所以从大到校遍历w才不会过早覆盖历史数据;
        for (int j = w; j > 0; j--)
        {
            if (j >= ws[i] && res[j] < (res[j - ws[i]] + vs[i]))
            {
                res[j] = res[j - ws[i]] + vs[i];
            }
        }
    }
    cout << "The max value is " << res[w] << endl;
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

0-1背包问题与动态规划的C/C++代码

那一年, 非计算机专业的我听到0-1背包和动态规划, 觉得很高大上, 其实, 动态规划无非就是寻找高中数学中所说的递推公式而已。最近又复习到0-1背包问题和动态规划, 所以打算用代码来玩玩。   ...
  • stpeace
  • stpeace
  • 2015年06月30日 23:53
  • 10789

0-1背包问题.c

  • 2015年06月07日 16:47
  • 691B
  • 下载

0 -1背包问题c++实现

  • 2013年05月05日 15:58
  • 28KB
  • 下载

基于C的动态规划0-1背包问题

#include #include int V[200][200];//前i个物品装入容量为j的背包中获得的最大价值  int max(int a,int b)  {     if(a>=b...

C++ 0-1背包问题源代码

  • 2012年01月03日 14:37
  • 26KB
  • 下载

0-1背包问题_算法设计C++

  • 2012年03月17日 19:48
  • 34KB
  • 下载

0-1背包问题回溯法C++代码

 /*给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?*/#include using namespace std;...

0-1背包问题源代码(C++)

  • 2011年11月18日 02:20
  • 151KB
  • 下载

C++ 实现 0-1 背包问题

1.什么是动态规划 首先介绍一下动态规划... 设计一个动态规划算法,通常可按照以下几个步骤进行: (1) 找出最优解的性质,并刻画其结构特征。 (2) 递归地定义最优解的值 (3) 以...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:0-1背包问题(c/c++)
举报原因:
原因补充:

(最多只允许输入30个字)