数据结构——01背包问题

记得以前学数据结构的时候,经常能看到关于背包问题的题目,好像acm比较多一点,心底觉得比较难。这两天看了一下,感觉想复杂了、、、

0-1 背包问题是给定 n 种物品和一个容量为 C 的背包,物品 i 的重量是 wi,其价值为 vi,每样物品只可取一次,并希望不超容量的前提下,能拿到价值最多的物品

我们假设一个情景,有5件物品,(重量,价值)分别为A(2,3),B(4,5),C(3,3),D(6,8),E(4,6),包容量为10

我们需要绘制出一个表

 012345678910
A00333333333
B00335588888
C0033568881111
D00335688111113
E00336699111214

A0表示只有A物品的情况下,背包容量为0,则能容纳最大价值为0

B2表示只有A和B物品的情况下,背包容量为2,则能容纳的最大价值为3

01背包问题,因为每件物品只有一件,考虑的是是否将其放入背包。而表中的每一个数据,也是由两个数据决定的,就拿C5这个数据来说,他参考的是B5和B2的值:参考B5是不放入C的情况;参考B2是想去放入C,因为背包容量为5,那么就要考虑仅有A、B存在时,背包容量为3时的最大价值

所以重点是如何去构建二维数组。第一行和第一列比较特殊,可以直接填写;数组中其它元素可以通过比较来获得,不过需要比较一下背包容量和将要放入物品的重量,比如说C5,5要大于C重量3的,因而可以比较B5与B2的大小,要是填写C2的话,就只能参考B2了

C++代码

#include<iostream>
#define N 5
#define C 10

using namespace std;

typedef struct ITEM{
    int weight;
    int value;
}item;

int main(){

    ITEM item[N];
    int ans[N][C+1];

    for(int i=0;i<N;i++){
        cin>>item[i].weight>>item[i].value;
    }

    for(int i=0;i<N;i++){
        for(int j=0;j<C+1;j++){
            if(i==0||j==0){
                if(j<item[i].weight)
                    ans[i][j]=0;
                else
                    ans[i][j]=item[i].value;
            }
            else{
                if(j<item[i].weight)
                    ans[i][j]=ans[i-1][j];
                else
                    ans[i][j]=ans[i-1][j]>ans[i-1][j-item[i].weight]+item[i].value?ans[i-1][j]:ans[i-1][j-item[i].weight]+item[i].value;
            }
        }
    }

    for(int i=0;i<N;i++){
        for(int j=0;j<C+1;j++)
            cout<<ans[i][j]<<" ";
        cout<<endl;
    }

    return 0;

}

运行结果:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值