关于01背包的理解

关于01背包的理解

前段时间自学了01背包,但是还有很多地方并不太理解,所以写一篇博客整理一下疑问所在和已经理解的部分。

01背包例题:
有N件物品和一个容量为V的背包。第i件物品的重量是c[i],价值是w[i]。
求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。

洛谷P2871 AC代码以及注释:

#include<cstdio>
#include<iostream>
using namespace std;

struct node//使用结构体存储
{
    int c;
    int w;
}a[23333];

int n, m, f[23333333];//因为f是记录背包容量的 所以一定要把f数组开到大于总容量

int main()
{
    scanf("%d%d", &n, &m);//n是物品数量 m是背包最大容量 
    for(int i = 1; i <= n; i++) scanf("%d%d", &a[i].c, &a[i].w);
    //a[i].c是重量 a[i].w是价值
    for(int i = 1; i <= n; i++)//n件物品 
    {
        for(int v = m; v >= a[i].c; v--)
        {
            //f[v]表示重量不超过v的最大价值 
            //v>=a[i].c是使得v-a[i].c>=0 
            //因为小于a[i].c的肯定装不下a[i] 所以不需要计算 
            //这里通过第一个for循环枚举过了所有物品 
            //这样就记录出了每件物品放入或者不放入的后果 
            f[v] = max(f[v], f[v - a[i].c] + a[i].w); 
            //f[v]:不选的价值; 
            //f[v-a[i].c]+a[i].w:选择后的价值; 
            //v-a[i].c:背包中还剩下的空间; 
            //后面一项的本质就是背包中还剩下的空间所占有的最大价值 
            //加上a[i].c大小的空间本身所带有的价值 
        }
    }
    printf("%d", f[m]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值