动态规划01背包与完全背包的C语言实现

0-1背包问题(Knapsack Problem)-动态规划方法(C语言递归和迭代) 背包问题 C语言递归 C语言迭代 动态规划方法 阅读详情

01背包是基础的背包问题,即容量为v的背包, 给你n件物品, 每件物品只有一件, 每件物品所占体积vi, 价值wi已知,求此背包所能容纳的前提下,让在其中物品价值最大。

此问题状态方程为发f[i][v] = max(f[i-1][v], f[i-1][v-vi[i]]+wi[i]), 即前i件物品放入容积为v的背包中得到的最大价值。

因为每件物品只有一件,所以第i件物品有两种选择, 即放或不放。

max(f[i-1][v], f[i-1][v-vi[i]]+wi[i])中,f[i-1][v]即选择不放, 价值保持放入i-1 个物品时的价值;
而f[i-1][v-vi[i]]+wi[i]即选择将第i件物品放入, 从其中选择较大的值就是即为前i件物品放入容积为v的背包得到的最大价值,最后f[n][v]就是要求的价值最大值;

code:
for(i = 0;i<n;i++)
        {
            for(j = vi[i];j<=v;j++)
            {
                f[i][j] = max(f[i-1][j], f[i-1][j-vi[i]]+wi[i]);
            }
        }

另外, 还可用一维数组代替二维数组的方法实现空间优化,即用最新的一组数据代替原先的上一组数据,不过此方法写循环式需要逆序循环, 即二层循环从v开始一直到vi[i],这样就保证了每个物品只拿一次,而顺序则不能保证,可能拿多次。
于是f[v] = max(f[v], f[v-vi]+wi[i], 最后的f[v]即为要求的最大价值。

code:
for(i = 0;i<n;i++)
        {
            for(j = v;j>=vi[i];j--)
            {
                f[j] = max(f[j], f[j-vi[i]]+wi[i]);
            }
        }

例题1:
Problem Description

多组输入。

对于每组输入,第一行有两个整数N,X(1 < = N < = 100,1 < = X < = 1000),分别表示哈士奇的数量和高数巨的钱数

对于每组数据,输出一个整数,表示高数巨最多可以获得的萌值,每组输出占一行

Example Input
2 100
50 20
60 40
3 100
20 55
20 35
90 95
1 10
20 50
Example Output
40
95
0
明显的01背包问题,这里所带的钱就相当于背包的体积,萌值就是价值,每条二哈的价钱可看做每个物品所占的体积。
code:
#include<stdio.h>
#include<string.h>
int max(int a, int b)
{
    if(a>b) return a;
    else return b;
}
int main()
{
    int b[1200];
    int n, x, pi[1200], mi[1200], i, j, a;
    while(~scanf("%d%d", &n, &x))
    {
        memset(b, 0, sizeof(b));
        for(i = 0;i<n;i++)
        {
            scanf("%d%d", &pi[i], &mi[i]);
        }
        for(i = 0;i<n;i++)
        {
            for(j = x;j>=pi[i];j--)
            {
                b[j] = max(b[j], b[j-pi[i]]+mi[i]);
            }
        }
        printf("%d\n", b[v]);
    }
}

有了01背包基础,接下来的完全背包聚会简单很多,完全背包实际上就是将每种物品的数量从一件变为无限件。那么设某i件物品拿k件,那么状态方程为

f[i][v]=max(f[i-1][v-k*v[i]]+k*w[i]|0<=k*v[i]<=v),这样需要三层循环,找出k为何值时使得f得到最大值;

另外完全背包也可以使用一维数组进行空间优化, 可以用01背包提到过的正序循环,这样就可以保证每件物品拿多次。

01背包中要按照v=V..0的逆序来循环。这是因为要保证第i次循环中的状态f[i][v]是由状态f[i-1] [v-c[i]]递推而来。换句话说,这正是为了保证每件物品只选一次,保证在考虑“选入第i件物品”这件策略时,依据的是一个绝无已经选入第i件物品的 子结果f[i-1][v-v[i]]。而现在完全背包的特点恰是每种物品可选无限件,所以在考虑“加选一件第i种物品”这种策略时,却正需要一个可能已选入第i种物品的子结果f[i][v-v[i]],所以就可以并且必须采用v=0..V的顺序循环。(本段节录自背包九讲)
code:
for(i = 0;i<n;i++)
        {
            for(j = vi[i];j<=v;j++)
            {
                f[j] = max(f[j], f[j-vi[i]]+wi[i]);
            }
        }

例题1:

Problem Description
话说,上次小P到伊利哇呀国旅行得到了一批宝藏。他是相当开心啊,回来就告诉了他的好基友小鑫,于是他们又结伴去伊利哇呀国寻宝。
这次小P的寻宝之路可没有那么的轻松,他们走到了一个森林,小鑫一不小心被触发了机关,被困在了一个大笼子里面,笼子旁边上有一道题目和一个密码锁,上面说只要解出此题输入密码即可救出被困人。小鑫不是很聪明,所以他做不出来,他知道小P很笨,更解不出来。所以他就让小P独自回去,不用管他。但是小P重情重义不会抛弃他离去。他说:“不,好基友一起走!”。于是就感动了上帝,上帝特派你来替他们解决问题。聪明的你要加油了啊!
题目描述:给你n种物品和一个体积为v的包包。每种物品有无数种,体积是vi价值是wi。求出包包v所能装的最大价值的东西。
Input
多组输入。第一行有两个正整数n(0<n<=10000), v(0<v<= 10000)。接下来两行每行有n个数字。第一行表示每种物品的价值wi(0<wi<100),第二行表示每种物品的体积vi(0<vi<100)。
Output
输出最多可以得到的价值。输出结果救出小鑫。
Example Input
5 20
1 2 3 4 5
2 6 3 5 4
Example Output
25
code:
#include<stdio.h>
#include<string.h>
int max(int a, int b)
{
    if(a>b) return a;
    else return b;
}
int main()
{
    int n, v, vi[10010], wi[10010], a[10010];
    int i, j;
    while(~scanf("%d%d", &n, &v))
    {
        memset(a, 0, sizeof(a));
        for(i = 0;i<n;i++)
        {
            scanf("%d", &wi[i]);
        }
        for(i = 0;i<n;i++)
        {
            scanf("%d", &vi[i]);
        }
        for(i = 0;i<n;i++)
        {
            for(j = vi[i];j<=v;j++)
            {
                a[j] = max(a[j], a[j-vi[i]]+wi[i]);
            }
        }
        printf("%d\n", a[v]);
    }
}




01背包问题和完全背包问题 01背包 01背包字面意思来看0就是不拿,1就是拿,且每次只能拿一个物品放入背包。 开二维数组的状态方程: 此情景为往固定容量的背包里装物品,使包内物品为最大价值 实际上就是在每个物品的基础上,遍历所有可能的背包空间,如果放得下去就比较放与不放对价值的影响 一维数组的状态方程: ... 阅读详情

相关推荐

各种动态规划算法的C语言

希望这些C语言实例对您有帮助。

m0_58464499的博客 326

C语言-背包问题

接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 种物品的体积和价值。求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。第一行两个整数 N,V,用空格隔开,分别表示物品种数和背包容积。第 i 种物品的体积是 vi,价值是 wi。

hqyaii的博客 2714

0-1背包问题(C语言源码)

人工智能,C语言,源码,算法,0-1背包问题 直接可以运行,没有错。

算法实验2:0-1背包问题的动态规划算法实现

0-1背包问题的动态规划算法实现 一、实验目的和要求: 1.掌握动态规划算法思想。 2.掌握最优子结构原理。 3.了解动态规划一般问题,并利用动态规划解决0-1背包问题。 二、实验环境: VS2019 – .cpp文件 三、算法描述及实验步骤 1.问题描述: 给定n个物品和一个背包。物品i的重量为wi,价值为vi,背包容量为c。 如何选择装入背包中的物品,使得装入背包的物品的价值最大? 注:每种物品i只有两种选择,装入或者不装入,既不能装入多次,也不能只装入一部分。 2.问题形式化描述: 给定

你说的白是什么白_ 2923

QGC二次开发实战指南(一):从零构建自定义地面站界面

本文详细介绍了QGC二次开发实战指南,从零开始构建自定义地面站界面。通过QT和QML技术结合MAVLINK协议,开发者可以打造适合特定业务场景的无人机监控系统,提升操作效率与用户体验。文章包含环境搭建、界面设计、数据绑定等完整开发流程,是QGC二次开发的实用教程。

weixin_28693683的博客 496

【WiFi软件开发】IOCTL和Netlink----用户空间和内核空间交互的两种方式

linux开发中通常会涉及用户空间和内核模块的交互。本文介绍了两种典型的用户空间和内核模块通信方式:ioctl和netlink

liuwe1ye的博客 2348

动态规划解决01背包与完全背包问题的C语言实现

动态规划是解决最优化问题的经典算法范式,通过将问题分解为重叠子问题并存储中间结果来实现高效求解。其核心在于状态定义与状态转移方程的设计,在资源分配、路径规划等领域有广泛应用。背包问题作为动态规划的典型应用场景,包含01背包(物品不可重复)和完全背包(物品可重复)两种基础形态。在C语言实现时,需要注意数组内存管理、索引边界处理等技术细节,通过伪代码先行和滚动数组优化等工程实践提升代码质量。本文以清晰的代码示例展示两种背包问题的完整解法,并给出空间优化、测试用例设计等实用技巧。

weixin_29188997的博客 164

别再到处找DEM了!手把手教你免费下载90米、30米、12.5米全球高程数据(附国内网盘链接)

本文详细介绍了如何免费获取全球90米(SRTM3)、30米(ASTER GDEM)和12.5米(ALOS)高精度DEM数据,并提供了国内网盘链接以绕过国际平台访问障碍。通过对比不同数据源的特点和适用场景,帮助用户根据项目需求选择最合适的DEM数据,同时分享了数据处理和质量提升的实用技巧,实现从数据获取到应用的无缝衔接。

weixin_28725949的博客 669

[C语言]背包问题:从原理到代码,吃透经典动态规划

背包问题作为动态规划的入门经典题型,万变不离其宗,核心都是在有限背包容量下,通过状态转移实现价值最大化。本文详解的01 背包、完全背包、多重背包,是最基础也最常用的三类模板,吃透三者的逻辑差异和代码写法,足以应对绝大多数背包类题目。01 背包是根基,每件物品仅可选一次,必须逆序遍历背包容量,避免重复选取;完全背包是延伸,物品可无限选取,只需将遍历顺序改为正序,其余逻辑与 01 背包完全一致;多重背包则是二者的结合,每件物品有固定选取上限,通过三层循环枚举数量,本质是带数量约束的 01 背包变种。

2501_93275026的博客 457

MatterPort3D 数据集下载

【代码】MatterPort3D 数据集下载。

qq_44106838的博客 6781

学术版GPT安装教程——保姆版(附带原生GPT注册教程)

学术版GPT图文安装教程

DBenD的博客 2万+

C++背包01与完全背包

#include #include int max(int a1,int a2) { return a1=a1>a2?a1:a2; } struct bag { int v; int pay; }s[10006]; int dp[10005]; int main() { int n,i,j,m,k; while(scanf("%d%d",&n,&m)!

LieYingZhiYan的专栏 1245

第1期技术: DQN算法原理及实现过程

利用神经网络近似值函数的方法表示为: V^(s,w)≈Vπ(s)q^(s,a,w)≈qπ(s,a) \hat{V}(s, w) \approx V_{\pi}(s) \\ \hat{q}(s, a, w) \approx q_{\pi}(s, a) V^(s,w)≈Vπ​(s)q^​(s,a,w)≈qπ​(s,a) 那么具体的工作过程是怎样实现的? 以及如何从端到端的过程,本文将讲解Deep Q Network(DQN, 而这正是由DeepMind于2013年和2015年分别提出的两篇论文《Playi

深度强化学习实验室:一个“开源开放、共享共进”的强化学习学术组织。 4953

应用C编程实现01背包问题——动态规划

应用C编程实现01背包问题——动态规划

ILOVEMISSLIU的博客 1509

Qt多线程实战:如何优雅地处理Modbus设备通信中的线程安全问题

本文深入探讨了在Qt框架下实现Modbus设备通信时的多线程安全问题,提供了优雅的解决方案。通过生产者-消费者模型、任务队列与锁机制等设计模式,有效解决了界面卡顿、数据包错乱等问题。文章还详细介绍了对象生命周期管理、信号槽连接类型选择等关键实现细节,帮助开发者构建稳定可靠的Modbus通信模块。

weixin_30897233的博客 483

【DRAM存储器五十一】LPDDR5介绍--DFE与Pre-Emphasis

简述LPDDR5的DFE和预加重应用设置

highman110的博客 705

【C语言】动态规划---01背包/完全背包

本文系统讲解了0-1背包和完全背包问题的动态规划解法。0-1背包中物品只能选一次,采用倒序遍历;完全背包中物品可无限选,采用正序遍历。两种方法都从二维DP入手,再优化为一维滚动数组。通过具体示例和表格演示了状态转移过程,并对比了两种背包的核心差异。最后以完全平方数问题为例,展示了如何将实际问题转化为完全背包模型,并给出相应的DP解法。全文通过清晰的逻辑和直观的示例,帮助读者彻底理解背包问题的解题思路。

fufu428的博客 653

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

背包问题总结(01背包、完全背包、多重背包)

1、 01背包问题 有n个物品,每个物品只有一件。 动归方程: (1)  二维数组解法      dp[i][j]=max{dp[i-1][j-w[i]]+v[i] , dp[i-1][j]}; (2)  一维数组解法      dp[j]=max{dp[j-w[i]]+v[i] , dp[j]} 附代码: HDU 2602 Bone Collector 二维数组: #in

L-75的专栏 1327

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

背包初步了解

0/1 背包问题动态规划详解及C代码 动态规划是用空间换时间的一种方法的抽象。其关键是发现子问题和记录其结果。然后利用这些结果减轻运算量。 比如01背包问题。 /* 一个旅行者有一个最多能用M公斤的背包,现在有N件物品, 它们的重量分别是W1,W2,...,Wn, 它们的价值分别为P1,P2,...,Pn. 若每种物品只有一件求旅行者能获

u013087645的专栏 683

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

动态规划——背包问题(一)

动态规划——背包问题(一) 背包问题的基本描述: 有nnn件物品,第iii件物品的重量为w[i]w[i]w[i],价值为p[i]p[i]p[i],将这些物品放入一个大小为VVV的背包,要求使得物品的总价值PPP尽量大。 则得到 P=∑p[i] P = \sum p[i] P=∑p[i] V≥∑w[i] V \geq \sum w[i] V≥∑w[i] 当要求物品恰能放入背包时有 ∑w[i]=V \sum w[i] = V ∑w[i]=V 背包问题可以分为以下几类,按照复杂程度排序为 01背包问题 多重背包

私のBookShelf 236

完全背包(C语言)

完全背包 与01背包不同之处就在于 它的物品可以取用无数次 可以研究一下的它的状态转移方程 所以从图中的推导就可以看出 将01背包滚动数组的逆序更新转换为顺序更新就行 因为根据状态转移方程可以看出 用到的是第i行的数据,所以需要顺序更新滚动数组 代码如下 #include<stdio.h> int f[2000]; int main() { int n,m; scanf("%d%d",&n,&m); for(int i = 0;i < n;i++){ int .

Mai___的博客 544

poj 1014

题目da #include #include #include #define MAX 70010 int dp[2*MAX]; int a[10]; int inline max(int a,int b) {     if(a>b) return a;     else    return b; } int solve(int n,int v) {  

zongyan0531的专栏 456

1.基于C的背包问题多讲(01背包)

有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。第 i 件物品的体积是 vi,价值是 wi。求解将哪些物品装入背包 ,可使这些物品的总体积不超过背包容量量,且总价值最大。输出最大价值。 输入格式 第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。 接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。 输出格式 输出一个整数,表示最大价值。 数据范围 0<N,V≤1000 0<vi,wi≤1000 输入样例 4 5 1 2 2 4

weixin_44910502的博客 231

NYOJ 311 完全背包

题目链接 对于背包的各种问题,其实感觉都还没有理解到位。。感觉不太能理解为何背包问题是从前向后推,而完全背包是从后向前推,,虽然之前把序列来来回回输出了好多遍,现在貌似还不是那么清晰。。遇到这个问题百度了一下代码,竟如此简单。。好吧。。我就先借这代码记住一些背包的知识,随着对动态规划理解的深入,以后再搞个背包的专题弄明白。。 dp[i]=max(dp[i],dp[i-wi]+ci)//代表占用的

xj13821328013的博客 315

动态规划——01背包与完全背包问题

找容量:题目要你达到的“总数”、“目标值”、“限制条件”是啥?那就是背包容量。找物品:数组里的每个元素有什么属性?它占据多少容量?能带来什么价值?定规则每个物品只能用一次 → 01背包(容量倒序每个物品无限用 → 完全背包(容量正序求最大价值 →max。求能不能 →dp[j]用布尔值。求方案数 →dp[0]=1,累加。

2503_94655346的博客 468

AcWing 02完全背包问题

关键区别在于遍历顺序:01背包使用倒序遍历保证物品只选一次,而完全背包使用正序遍历允许物品被多次选择。文章通过对比两种背包问题的代码差异,深入解释了正序遍历的原理,并提供了完整的C语言实现代码,帮助读者理解完全背包问题的本质和实现细节。相较于01背包问题,这个问题的不同点在于,一种东西有无数个,这跟01背包问题类似于马尔科夫链的解法类似,同样也是只考虑前一种选法,只不过,遍历从倒序变成了正序,如下所示。第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。输出一个整数,表示最大价值。

2502_93975390的博客 176
上一篇: sdut acm 顺序表应用1:多余元素删除之移位算法
下一篇: sdut acm 顺序表应用4:元素位置互换之逆置算法
shadowam
博客等级 码龄10年 62粉丝 168原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值