01背包两维背包

chenguang9239 chenguang9239     2022-08-26     117

关键词:

#include <iostream>
#include <algorithm>

using namespace std;

/******************************** 01背包 */
#define N 5
#define M 12
int value[N + 1] = { 0, 6, 3, 5, 4, 6 };
int weight[N + 1] = { 0, 2, 2, 6, 5, 4 };

//#define N 5
//#define M 8
//int value[N + 1] = { 0, 1, 2, 3, 10, 1 };
//int weight[N + 1] = { 0, 1, 2, 3, 7, 1 };

int dp[N + 1][M + 1] = { 0 }; //dp[i][j],前i个物品,容量为j的背包,达到的最大价值

int dp1[M + 1] = { 0 }; //将二维空间压缩到一维dp[j],对i迭代,前i个物品,容量为j的背包,达到的最大价值
int path[N + 1][M + 1] = { 0 }; //打印最佳方案的内容使用,path[i][j]表示
                                //前i个物品,容量为j的背包,达到最佳方案时,第i个物品是否加入了背包。0/1


int main()
{

for( int i = 0; i <= N; i++ )
{
    dp[i][0] = 0;
}
for( int j = 0; j <= M; j++ )
{
    dp[0][j] = 0;
}

    //dp[i][j],前i个物品,容量为j的背包,达到的最大价值
    for( int i = 1; i <= N; i++ )
    {
        for( int j = 1; j <= M; j++ )
        {
            if( weight[i] > j )
            {
                dp[i][j] = dp[i-1][j];
                continue;
            }
            dp[i][j] = max( dp[i-1][j], dp[i-1][ j-weight[i] ] + value[i] );
        }
    }
    /******************************** 01背包 输出选择 */
    cout << dp[N][M] << endl;
    cout << "We selected: ";
    int i = N, j = M;
    while( i > 0 && j > 0 )
    {
        if( dp[i][j] > dp[i-1][j] ) //说明选择了第i个物品
        {
            cout << i << " ";
            j -= weight[i];//更改背包的容量j
        }
        i--;
    }







for( int j = 0; j <= M; j++ )
{
    dp1[j] = 0;
}
    //将二维空间压缩到一维dp[j],对i迭代,第i个物品,容量为j的背包,达到的最大价值
    //在第i轮(考虑第i个物品是否入到容量为j的背包里)的最大价值,会用到第i-1轮
    //(考虑第i-1个物品是否放到容量小于或等于j的背包里)的最大价值。
    //因此j的循环要从大到小,这样才保证在第i轮计算dp[j]使用的是第i-1轮的dp[J](J<=j)。

    ///在对i的一次迭代中,如当i=1时,把前i个物品放入容量为j的背包里的最大价值,不依赖于把前i个物品放入容量
    ///小于j的背包里的最大价值,即相同的i时,第i轮dp[j]的计算不依赖第i轮的dp[J],(J<j)。
    for( int i = 1; i <= N; i++ )
    {
        for( int j = M; j >= 1; j-- )
        {
            if( weight[i] > j )
            {
                //dp1[j] = i-1轮的dp1[j],即不变;这个if判断保证了下面的j-weight[i]不会越界。
                continue;
            }
            if( dp1[j] < dp1[ j-weight[i] ] + value[i] )
            {
                path[i][j] = 1;//物品i加入了背包
            }
            dp1[j] = max( dp1[j], dp1[ j-weight[i] ] + value[i] );
        }
    }
    /******************************** 01背包 输出选择 */
    cout << endl << dp1[M] << endl;
    cout << "We selected: ";
    i = N; j = M;
    while( i > 0 && j > 0 )
    {
        if( path[i][j] == 1 ) //说明选择了第i个物品
        {
            cout << i << " ";
            j -= weight[i];//更改背包的容量j
        }
        i--;
    }

    return 0;
}

两维背包:

问题描述:1. n个0,m个1

     2. 若干种物品,分别由0和1组成,这些物品是:1, 00, 100

       3. 最多组成多少种物品。

     -------------两维背包,第一维是0的容量为n,第二维是1的容量为m,dp[i][k][j]表示在第一个背包容量为k,第二个背包容量为j的时候,取前i个物品达到的最高价值。这里的价值就是物品的个数。dp[i][k][j]可以压缩到两维dp[k][j]。

#include <iostream>
#include <string>
#include <vector>

using namespace std;

vector< string > item; //没有用到

int weight0[21] = { 0 };
int weight1[21] = { 0 };
int dp[501][501] = { 0 };

int main()
{
    int n, m, x;
    cin >> x >> n >> m;
    item.push_back("");
    string s;
    for( int i = 0; i < x; i++ )
    {
        cin >> s;
        item.push_back( s );

        int cnt = 0;
        for( int ind = 0; ind < s.length(); ind++ )
        {
            if( s[ind] == 0 )
            {
                cnt++;
            }
        }
        weight0[i+1] = cnt;
        weight1[i+1] = s.length() - cnt;
        //cout << "i: " << i+1 << " " << weight0[i+1] << " " <<weight1[i+1] << endl;
    }

    for( int i = 1; i <= x; i++ )
    {
        for( int k = n; k > 0; k-- )
        {
            for( int j = m; j > 0; j-- )
            {
                if( weight0[i] > k || weight1[i] > j )
                {
                    continue;
                }
                dp[k][j] = max( dp[k][j], dp[ k-weight0[i] ][ j-weight1[i] ] + 1 );
            }
        }
    }

    cout << dp[n][m] << endl;
    return 0;
}

 

参考链接:http://blog.csdn.net/wumuzi520/article/details/7014559

       http://love-oriented.com/pack/P01.html

背包问题(01背包,完全背包,多重背包)

...http://www.cnblogs.com/daoluanxiaozi/archive/2012/05/06/2486105.html 背包问题,经典有背包九讲。01背包 不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票(记住,只有一张钞票),为了防止自己在战斗中频繁的死掉,他决定给自己买一些... 查看详情

01背包模板全然背包and多重背包(模板)

...g.com/tanky-woo/archive/2010/07/31/121803.html模版就直接贴代码:01背包模板:/*01背包问题01背包问题的特点是,">每种物品仅有一件。能够选择放或不放。01背包问题描写叙述:有N件物品和一个容量为V的背包 查看详情

01背包,完全背包,多重背包,混合背包

详见大牛背包九讲(下载地址:http://pan.baidu.com/s/1b9edXW)1//Class->物品种类,val->价值,room->所占空间,num->物品数量,Room->背包容量23#include<stdio.h>4constintmaxn=1e6;56intbag[maxn];7intRoom;89voidzero_one_bag( 查看详情

动态规划背包问题01背包完全背包多重背包

 一、01背包有N件物品和一个容量为V的背包。第i件物品的价格(即体积,下同)是w[i],价值是c[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。这是最基础的背包问题,总的来说就... 查看详情

动态规划_01背包_完全背包_多重背包_分组背包(代码片段)

目录动态规划问题结题思路:模板题链接:01背包思路:代码:完全背包思路:代码多重背包思路:代码:组合背包思路:代码:动态规划问题结题思路:模板题链接:01背包模板题完全背包... 查看详情

动态规划之背包问题-01背包+完全背包+多重背包(代码片段)

01背包有n种不同的物品,每种物品分别有各自的体积v[i],价值 w[i] 现给一个容量为V的背包,问这个背包最多可装下多少价值的物品。1for(inti=1;i<=n;i++)2for(intj=V;j>=v[i];j--)3dp[j]=max(dp[j],dp[j-v[i]]+w[i]);//dp[V]为所求完全背包0... 查看详情

01背包完全背包多重背包

参考(都有些错误):https://github.com/guanjunjian/Interview-Summary/blob/master/notes/algorithms/%E7%BB%8F%E5%85%B8%E7%AE%97%E6%B3%95/01%E8%83%8C%E5%8C%85.mdhttps://blog.csdn.net/na_beginning/article/details/6 查看详情

9大背包第一弹|01背包

今天学习01背包。因为01背包在暑假学习过,所以上网看了一下文章,就能写出来了。主要还是一种动态规划的思想,设置背包的【容量】进行增长,【物品】进行增长。只要满足【当前物品】的【价值】=max{      ... 查看详情

01背包

问题描述:给定N中物品和一个背包。物品i的重量是Wi,其价值位Vi ,背包的容量为C。问应该如何选择装入背包的物品,使得转入背包的物品的总价值为最大??在选择物品的时候,对每种物品i只有两种选择,即装入背包或不... 查看详情

动态规划-01背包

...,学长们很早之前就讲过了,然而我现在才来写。。。01背包01背包是在M件物品取出若干件放在空间为W的背包里,每件物品的体积为W1,W2……Wn,与之相对应的价值为P1,P2……Pn。01背包题目的雏形是:有N件物品和一个容量为V的... 查看详情

01背包+完全背包+多重背包+单调队列(代码片段)

01背包代码:逆序更新intn,m,f[105][N],dp[N];voidfun1()for(inti=1;i<=n;i++)//物品ifor(intj=1;j<=m;j++)//容量jif(j<w[i])f[i][j]=f[i-1][j];elsef[i][j]=max(f[i-1] 查看详情

01背包java实现(入门到精通)

一、什么是01背包  01背包是在M件物品取出若干件放在空间为W的背包里,每件物品的体积为W1,W2至Wn,与之相对应的价值为P1,P2至Pn。01背包是背包问题中最简单的问题。01背包的约束条件是给定几种物品,每种物品有且只有一... 查看详情

01背包与完全背包

01背包有一个体积为V的背包,有n个物品,每个物品都有体积vi和价值wi,在背包体积范围内,求能桌下的最大价值。这个问题中每个物品只能用一次。设dp[i][j]表示用前i个物品装体积为j的背包。那么第i个物品要么装要么不装:1... 查看详情

背包问题(01背包)(代码片段)

--------开始--------      每次用到背包问题就忘,今天特意把背包问题写下来,本篇只写01背包问题,至于其它的背包问题以后会陆续出现,大多数背包问题都是以01背包为原型来演变过来的,所以先介绍经典... 查看详情

01背包问题和完全背包问题(代码片段)

...coder上面的题目中看到的这个问题,总结一下。先看01背包问题。01背包问题:一个背包总容量为V,现在有N个物品,第i个物品体积为weight[i],价值为value[i],现在往背包里面装东西,怎么装能使背包的... 查看详情

01背包+滚动数组

01背包定义:在$M$件物品取出若干件放在空间为$V$的背包里,每件物品的体积为$V_1$,$V_2$至$V_n$,与之相对应的价值为$W_1$,$W_2$至$W_n$。01背包的约束条件是给定几种物品,每种物品有且只有一个,并且有权值和体积两个属性。... 查看详情

acwing(基础)---01背包和完全背包多重背包问题(代码片段)

初始化的细节问题我们看到的求最优解的背包问题题目中,事实上有两种不太相同的问法。有的题目要求“恰好装满背包”时的最优解,有的题目则并没有要求必须把背包装满。一种区别这两种问法的实现方法是在初始化的时候... 查看详情

算法----01背包问题和完全背包问题leetcode系列问题题解(代码片段)

背包问题1、01背包入门1.1二维背包1.2一维背包2、01背包问题2.1背包装最多问题416.分割等和子集1049.最后一块石头的重量II2.2凑满背包方法数问题494.目标和2.3双重维度问题474.一和零3、完全背包问题3.1凑满组合问题518.零钱兑换II3.2... 查看详情