c语言背包问题(动态规划解法)

c语言背包问题(动态规划解法)题目描述:有若干个物品要装进背包,并且每个物品有各自的价值,物品的数量、价值以及背包的容量由用户输入,求背包内能够存入的最大价值为多少,并且求出此时放入了哪些物品输入格式:第一行输入物品的容量r和物品个数n第二行输入每个物品的重量第三行输入每个物品的价值输出格式:第一行输出背包中能够存储的最大价值第二行输出此时背包中的物品编号思路分析:可以把这个问题看成是一个二维数组,行是物品编号,列是背包容量,若物品编号为2,背包容量为4,代表的则是当背包容量为..

大家好,又见面了,我是你们的朋友全栈君。

题目描述:

有若干个物品要装进背包,并且每个物品有各自的价值,物品的数量、价值以及背包的容量由用户输入,求背包内能够存入的最大价值为多少,并且求出此时放入了哪些物品

输入格式:

第一行输入物品的容量r和物品个数n

第二行输入每个物品的重量

第三行输入每个物品的价值

输出格式:

第一行输出背包中能够存储的最大价值

第二行输出此时背包中的物品编号

思路分析: 

  可以把这个问题看成是一个二维数组,行是物品编号,列是背包容量,若物品编号为2,背包容量为4,代表的则是当背包容量为4的时候,前两个物品的最大价值。因此当行为物品数,列为背包容量时,即容量为n的背包能够存储的最大价值。

  因此我们定义一个函数给全局变量二维数组赋值,返回二维数组右下角的值即可。

  那么怎么判断放入了哪些物品呢,此时可以根据算法来逆推,若当前物品在当前容量时的价值,与前一个物品在相同容量时的价值相等,则证明当前物品没有被放进背包。若不相等,则证明当前物品放进了背包,此时物品数-1,容量数减去当前物品的重量。

  因此,我们再定义一个函数来寻找背包内放入了哪些物品,并且还要定义一个全局数组,数组的长度就是物品数,数组里面默认都是0,如果在函数中判断放入了该物品,则物品编号对应的值赋1,最后在主函数中判断即可。,

样例输入:

10 3
3 4 5
4 5 6

样例输出: 

11
2 3

代码实现: 

#include<stdio.h>
int f[100][100];//构建最优矩阵,定义全局变量,默认赋0
int find[100];//定义一个数组,寻找背包内放入了哪些物品

int best(int r,int n,int *weight,int *value)//定义一个构建最优矩阵的函数
{     int i,j;

      for(i=0;i<=n;i++)
        f[i][0]=0;

        for(i=0;i<=r;i++)
        f[0][i]=0;

        for(i=1;i<=n;i++)
          for(j=1;j<=r;j++)
            {   if(weight[i]<=j&&f[i-1][j-weight[i]]+value[i]>f[i-1][j])
                   f[i][j]=f[i-1][j-weight[i]]+value[i];
                 else
                 f[i][j]=f[i-1][j];
            }
            return f[n][r];

}

void object(int r,int n,int *weight)//定义一个函数寻找背包里面放入了哪些物品,因为改变的是全局变量find数组的值,所以函数可以不必有返回值
{        int i,j=r;
        for(i=n;i>=1;i--)
          {   if(f[i][j]!=f[i-1][j])  //如果当前价值,比不放当前物品的价值不一样,则代表放入了当前物品
                {find[i]=1;j=j-weight[i];}
          }
}

int main()
{  int weight[100]={0};
   int value[100]={0};
   int r,n,i,maxvalue;//r为背包容量 n为物品数量 maxvalue为最大的背包价值
   scanf("%d%d",&r,&n);

   for(i=1;i<=n;i++)
     scanf("%d",&weight[i]);//输入物品的重量

    for(i=1;i<=n;i++)
      scanf("%d",&value[i]);//输入物品的价值

      maxvalue=best(r,n,weight,value);

    object(r,n,weight);

    printf("背包的最大价值为:%d\n",maxvalue);

    printf("背包里面存入了物品:");

   for(i=1;i<=n;i++)
     if(find[i]==1)printf("%d ",i);

     return 0;

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/159097.html原文链接:https://javaforall.net

(0)
上一篇 2022年7月14日 下午12:46
下一篇 2022年7月14日 下午12:46


相关推荐

  • c语言链表数据存入文件和读取文件

    c语言链表数据存入文件和读取文件c语言,链表数据存入文件和读取文件

    2022年5月5日
    40
  • linux下通过V4L2驱动USB摄像头

    linux下通过V4L2驱动USB摄像头目录目录前言 v4l2 解析 v4l2 介绍应用程序通过 V4L2 接口采集视频数据步骤相关结构体解析参考链接前言在移植罗技 C270 摄像头到 6818 的过程中 内核已经检测到了 USB 摄像头 但是直接用 OpenCV 的 API 比如 CvCapture cvCaptureFro intindex 接口 无法打开 USB 摄像头 至少目前我是这么认为的 然后 网上搜索答案

    2026年3月19日
    1
  • Mysql 主从复制 作用和原理

    Mysql 主从复制 作用和原理一、什么是主从复制?主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库,主数据库一般是准实时的业务数据库。您看,像在mysql数据库中,支持单项、异步赋值。在赋值过程中,一个服务器充当主服务器,而另外一台服务器充当从服务器。此时主服务器会将更新信息写入到一个特定的二进制文件中。并会维护文件的一个索引用来跟踪日志循环。这个日志可以记录并发送到从服务器的更新中去。当一台从服务器连…

    2022年4月19日
    41
  • springboot zuul网关_ubuntu网关服务器搭建

    springboot zuul网关_ubuntu网关服务器搭建目录一.Zuul网关二.Zuul服务的前期准备2.1注册中心EurekaServer的搭建2.2EurekaService的搭建三.Zuul服务搭建五.Zuul的访问六.Zuul的更多功能前言:博主一直力求做到写博客尽量的详细来减少大家花在踩坑上的时间,若有写的不好或错误的地方,还需各方大佬指正。一.Zuul网关网关,是一种网络关口,既然是…

    2022年8月15日
    7
  • eclipse自动补全设置_eclipse补全设置

    eclipse自动补全设置_eclipse补全设置Eclipse版本问题描述自动补全显示顺序不尽人意,如下:输入equals使用自动补全后,显然并不是我们希望使用的方法。解决方法1进入Windows选项卡下的Perferences,搜索ContentAssist,找到Java选项卡下的ContentAssist,选择Advanced选项卡。将其中内容配置为(即,将上下两部分的JavaProposals(Task-Focused)取消勾选,将JavaProposals勾选);之后就可以开心的使用自动补全啦!解决方法2这是

    2022年10月15日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号