一看就会的01简单背包问题

简介: 一看就会的01简单背包问题

相信大家和我一样,在刚开始写背包问题时因为不会动态规划而无从下手,其实简单背包问题真的很简单,只要你仔细阅读这篇文章,就会很快解决~

题目

给定n种物品和一背包。物品i的重量(体积)是w~i,其价值为v~i,背包的容量为C。问:应如何选择装入背包的物品,使得装入背包中物品的总价值最大。

要求:

* 系统给出的第一个数字是背包容量,第二个数字是物品件数,然后分别给出每件物品的重量,再分别给出每件物品的价值。

* 请依次输出装入背包的物品序号,总重量,总价值。

1.贪心算法

       首先我们想到的是贪心算法,用单位重量的价值的大小来判定此物体是否要放入包中,但是贪心算法不一定是最优解,为什么呢?

比如一个背包的最大容量是100

                    编号 1     2    3    4

一些物体的重量是50 10   60   40

他们的重量分别是50  2    30  40

显而易见单位重量价值排序为1>4>3>2

在贪心算法下,我们在取完1和4以后,在取3时发现超过容量,就不继续往后取u,但是实际上我们的2号物品重量刚好不超,并且还增加了总价值,这就是贪心算法的缺陷所在,他的解并非是最优解

   

 那么贪心算法无法解决,我们就来暴力枚举,枚举法(穷举法)得出来的一定是最优解哦~

2.枚举法

**算法描述(伪代码):**

for (i=0 to 2^n-1)

{

将 i 对应的二进制数按位存放到数组Y中;

尝试按照装包方案y进行装包,则背包中物品的重量为CurWeight, 价值为CurValue;

如果CurWeight>C,则丢弃该方案,继续尝试下一种方案;否则,若该方案优于以前的方案,即如果CurValue>Value,则暂存该方案:即X=Y,Value=CurValue, Weight= CurWeight。 继续循环;

}

       看了上述代码,可能你还会有些迷惑,简单的说,就是利用0与1的性质,取对应着乘以1,不取就对应着乘以0

1.定义W和V数组存放重量和价值,输入背包容量等信息

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<math.h>
int main()
{
  int c,k,n,i,j,m,V,W,MaxV=0,MaxW=0,count;
  scanf("%d %d", &c, &n);
  int w[1000] = { 0 };
  int v[1000] = { 0 };
  int arr[1000] = { 0 }, x[1000] = { 0 };
  for (i = 0; i < n; i++)
  {
    scanf("%d", &w[i]);
  }
  for (i = 0; i < n; i++)
  {
    scanf("%d", &v[i]);
  }

2.通过枚举取与不取的可能有n的2^n次方种可能,(根据排列组合,n个物体取或不取有2^n种可能性),物品的取与不取正好对应着将0和1分别排列组合的放入一个数组里面。

for (i = 1; i < pow(2, n); i++)
  {
    m = n-1;
    //枚举取与不取,方法就是让对应的价值和重量乘以1或0,此时将0与1放在和价值和重量对应顺序的位置,方便相乘
    for (j = 0; j < n; j++)
    {
      arr[m--] = (1&(i>>j)); 
    }

这里的(1&(i>>j))指的是将i右移j位2进制位以后与1的二进制位取并

3.将每一种1到2^n种可能性比较大小,先判断是否超过容量,在判断是否是最大价值,在每一次放入背包时一定要记得清空背包以便于下一次计算哦~

清空背包以便于下一次计算
    W = 0;
    V = 0;
    //将东西放入背包
    for (k = 0; k < n; k++)
    {
      W += arr[k] * w[k];
      V += arr[k] * v[k];
            背包现在的重量和价值
    }
    //比较是否超过容量
    if (W <= c)
    {
      //比较是否是最大价值
      if (V > MaxV)
      {
        MaxV = V;
        MaxW = W;
        count = 0;
        for (int h = 0; h < n; h++)
        {
          //应题目要求将序号存起来方便打印
          if (arr[h] == 1)
          {
            x[count++] = h+1;
          }
        }
      }
    }
  }

4.打印出结果即可

for (i = 0; i < count; i++)
  {
    printf("%d ", x[i]);
  }
  printf("%d %d", MaxW, MaxV);
}

完整代码

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<math.h>
int main()
{
  int c,k,n,i,j,m,V,W,MaxV=0,MaxW=0,count;
  scanf("%d %d", &c, &n);
  int w[1000] = { 0 };
  int v[1000] = { 0 };
  int arr[1000] = { 0 }, x[1000] = { 0 };
  for (i = 0; i < n; i++)
  {
    scanf("%d", &w[i]);
  }
  for (i = 0; i < n; i++)
  {
    scanf("%d", &v[i]);
  }
  for (i = 1; i < pow(2, n) - 1; i++)
  {
    m = n-1;
    for (j = 0; j < n; j++)
    {
      arr[m--] = (1&(i>>j)); 
    }
    W = 0;
    V = 0;
    for (k = 0; k < n; k++)
    {
      W += arr[k] * w[k];
      V += arr[k] * v[k];
    }
    if (W <= c)
    {
      if (V > MaxV)
      {
        MaxV = V;
        MaxW = W;
        count = 0;
        for (int h = 0; h < n; h++)
        {
          if (arr[h] == 1)
          {
            x[count++] = h+1;
          }
        }
      }
    }
  }
  for (i = 0; i < count; i++)
  {
    printf("%d ", x[i]);
  }
  printf("%d %d", MaxW, MaxV);
}

以上就是简单01背包问题的解决方法,如果大家有更简单更优的解法,欢迎大家在评论区讨论哦~

       写博客不易,希望大家多多关注和点赞,我会一直更新我的博客和大家一起进步的!

目录
相关文章
|
存储 算法 测试技术
大模型落地的必经之路 | GPTQ加速LLM落地,让Transformer量化落地不再困难
大模型落地的必经之路 | GPTQ加速LLM落地,让Transformer量化落地不再困难
454 0
|
存储 安全 编译器
【C++ 17 新功能 std::visit 】深入解析 C++17 中的 std::visit:从原理到实践
【C++ 17 新功能 std::visit 】深入解析 C++17 中的 std::visit:从原理到实践
1134 1
|
机器学习/深度学习 人工智能 测试技术
【自定义插件系列】0基础在阿里云百炼上玩转大模型自定义插件
本文介绍了如何在阿里云百炼平台上创建大模型自定义插件,以增强AI模型功能或适配特定需求。通过编程接口(API)或框架设计外部扩展模块,开发者可在不修改底层参数的情况下扩展模型能力。文章以万相文生图V2版模型为例,详细说明了创建自定义插件的五个步骤:新建插件、创建工具、测试工具、复制第二个工具及最终测试发布。同时,提供了官方文档参考链接和具体参数设置指导,帮助用户轻松实现插件开发与应用,推动AI技术在各行业的广泛应用。
1562 0
|
机器学习/深度学习 并行计算 调度
构建高效GPU算力平台:挑战、策略与未来展望
【8月更文第5天】随着深度学习、高性能计算和大数据分析等领域的快速发展,GPU(图形处理器)因其强大的并行计算能力和浮点运算速度而成为首选的计算平台。然而,随着模型规模的增长和技术的进步,构建高效稳定的GPU算力平台面临着新的挑战。本文旨在探讨这些挑战、应对策略以及对未来发展的展望。
812 1
|
JavaScript
解决Elementui输入框(text)与文本域(textarea)字体不一样问题
解决Elementui输入框(text)与文本域(textarea)字体不一样问题
918 5
|
消息中间件 运维 Serverless
阿里云函数计算是一种FaaS(Function as a Service)云服务
【4月更文挑战第17天】阿里云函数计算是一种FaaS(Function as a Service)云服务
2263 3
|
数据采集 监控 供应链
shopee商品列表数据接口丨关键词搜索shopee商品数据采集
shopee商品列表数据接口丨关键词搜索shopee商品数据采集
|
监控 Dubbo Linux
【分布式流控组件 Sentinel 快速入门】——图文详解操作流程(下)
【分布式流控组件 Sentinel 快速入门】——图文详解操作流程(下)
313 0
|
机器学习/深度学习 传感器 算法
【信号分析】基于HHT算法谐波和间谐波分析附Matlab代码
【信号分析】基于HHT算法谐波和间谐波分析附Matlab代码