01背包模板总结

  前两天学习了一下动态规划中的一种背包问题,发现网上绝大多数模板都叙述的含糊不清,
关键部分看不懂让人感觉很难受,今天我就详细叙述一下01背包。
  首先的问题当然是什么叫做01背包。
  01背包:先举个01背包的题
    有编号分别为a,b,c,d,e的五件物品,它们的重量分别是1,2,5,6,7,它们的
  价值分别是1,6,18,22,28,每件物品数量只有一个,现在给你个承重为11的背包,如何
  让背包里装入的物品具有最大的价值总和?
    怎么个意思,就是物品只有一个,不能重复放,将哪些物品装入背包可使这些
  物品的重量总和不超过背包容量,且价值总和最大,这就是01背包问题。

一,模板
以上面的01背包的问题为例子

#include<stdio.h>
int max[500][500];

int main(void)
{
    int w=11;                                         //背包容量
    int n=5;                                          //物品数量
    int value[5]={1,6,18,22,28};                      //相互对应的重量与价值
    int weight[5]={1,2,5,6,7};                        


    for(int i=0;i<=w;i ++)                             //M[n,W]
        max[0][i]=0;                                   max为最大价值数组,数组一维


    for(int j=1;j<=n;j++)                            //外层遍历放到第几个物品                                                             
    {                                                //想要求背包上限为11时的最大价值就要知道背包
        for(int k=1;k<=w;k++)                        //上限为1--10时的最大价值,内层遍历背包容量           
        {
            if(weight[j-1]>k)
            {                                        //第j个物品对应重量的下标减1,从0开始。
                max[j][k]=max[j-1][k];               //当加入的一个物品重量大于k,这个物品一定不能选
            }
            else
            {
                int a=max[j-1][k];                          //不选第j个物品, 也就是遍历之前的一个物品时的     
                                                            //最大价值           
                int b=value[j-1]+max[j-1][k-weight[j-1]];   //可以选第j个物品,选择这个物品
                /*
                    选第j个物品时,背包剩余容量为[k-weight[j-1]],所以你需要知道当物品遍历到[j-1]时,
                    此时的最大价值,用当前物品价值加上max[j-1][k-weight[j-1]]对应的最大价值
                */
                max[j][k]=a>b ? a:b;//选择第j个和不选第j个物品,那个大,返回哪个;
            }
                /*
                特别注意j,k代表着当背包容量为k时,往进放到第j个物品的最大价值,并且最重要保证遍历到第5个物品时,
                价值一定是最大的。
                */                                                                                                            
        }
    }
    printf("%d\n",max[n][w]);            //最终结果一定是当背包容量为w时,遍历到第n个物品时的最大价值
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值