基础算法(七)——动态规划【0/1背包问题】

  首先,对于动态规划,我来做一个简短的介绍,相信各位都看得懂。动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法。先给一道最简单的例题(小学奥数水平):

这就是一个模拟的动态规划法!

好了,现在开始认识一下最简单的动态规划实例:0/1背包

【问题描述】有一位旅行者要出远门,到商店里去筹备东西。在商店里,摆放了n样物品,每种物品有各自的体积,但是每种物品只有一件。这个旅行家有一个限制装V个体积的物品的背包,但是这个旅行家比较有钱,想买贵的东西。请编程求出:将哪些物品装入背包可使这些物品的费用总和不超过背包体积V,且价值总和最大。

乍一看到,感觉直接模拟暴力即可。但是,当数据量非常大的时候,这种方法就不显得十分的管用了。于是,我们打算用多的空间来换时间。

设数组dp[i,j]表示前i种物品装在体积为j的背包里所能获得的最大价值。存每件物品体积的数组为c,价值的数组为w

那么可以列出一个状态转移方程为:dp[i,j]:=max{dp[i-1,j],dp[i-1,v-c[i]+w[i]}。

所以稍作枚举即可。其实有点类似于记忆化搜索。

【参考程序】

 1 var
 2   c,p:  array[1..1000] of longint;
 3   i,j:  longint;
 4   f:    array[1..1000,1..1000] of longint;
 5   n,m,x:longint;
 6 Function max(a,b:integer):longint;
 7 begin
 8   if a>b then max:=a
 9     else max:=b;
10 end;
11
12 BEGIN
13   readln(n,m);
14   for i:=1 to n do
15   readln(c[i],p[i]);
16   for i:=1 to n do
17     for j:=1 to m do
18       if j>=c[i] then f[i,j]:=max(f[i-1,j],f[i-1,j-c[i]]+p[i])
19         else  f[i,j]:=f[i-1,j];
20   writeln(f[n,m]);
21 END.

其实,在空间上还是可以进一步优化的,如下:注意第二次循环是downto

 1 var a:array[0..100000]of longint;
 2 v,p,w,c:array[0..100]of longint;
 3 n,m,i,j:longint;
 4 begin
 5   readln(m,n);{m代表可供选择的物品数量,n包的体积}
 6   for i:=1 to m do
 7     read(v[i],w[i]); {v[i],w[i]分别代表第i件物品的体积和价值}
 8   for i:=1 to m do
 9   for j:=n downto v[i] do {从放入第一件物品到第i件物品时体积的变化}
10     if a[j]<a[j-v[i]]+w[i]
11       then a[j]:=a[j-v[i]]+w[i];{比较放入j-1件物品和放入j件物品时价值谁大}
12    writeln(a[n]);
13 end.
时间: 2024-08-24 10:22:58

基础算法(七)——动态规划【0/1背包问题】的相关文章

动态规划算法实现部分——0/1背包问题

代码: import java.util.*; import java.util.Scanner; /* *动态规划思想解决0/1背包问题 */ public class Main{ public static void main(String[] args){ Scanner in=new Scanner(System.in); System.out.println("输入背包的容量"); int bagCap=in.nextInt(); //背包的容量 System.out.pri

关于贪心算法和动态规划的学习 - 背包问题为例

说到背包问题,我看到了很多分类,不同的类似问题,有不一样的解法,看到的最多的两种方式是贪心算法和动态规划,于我来说,更迫切的应该是要认识一下,这些算法的区别和相同的地方,所以这节就来找资料学习一下贪心算法和动态规划的区别. 这是找到的一个对我帮助最大的,源地址:https://www.cnblogs.com/Renyi-Fan/p/7741089.html 看之前先摘一下这几个解决方案的区别:摘自网上 "所以一个问题,该用递推.贪心.搜索还是动态规划,完全是由这个问题本身阶段间状态的转移方式决定

动态规划0—1背包问题

动态规划0-1背包问题 ? 问题描写叙述: 给定n种物品和一背包.物品i的重量是wi,其价值为vi,背包的容量为C.问应怎样选择装入背包的物品,使得装 入背包中物品的总价值最大? ? 对于一种物品,要么装入背包,要么不装.所以对于一种物品的装入状态能够取0和1.我们设物品i的装入状态为xi,xi∈ (0,1),此问题称为0-11背包问题. 过程分析 数据:物品个数n=5,物品重量w[n]={0,2,2,6,5,4},物品价值V[n]={0,6,3,5,4,6}, (第0位,置为0,不參与计算,仅

动态规划--0,1背包问题(再也不怕类似背包问题了)

这种类型问题三大要素:总重量.每件物品重量.每件物品价值,问最终能够塞进背包中的价值最大是多少?应该怎么选择物品? 当然也不一定是这些,例如上节所说的矿工挖矿:总人数.挖每座矿的人数.每座矿的金子数. 也就是说,只要出现了这三大要素,都可以视为0,1背包问题(物品不可拆分) 动态规划三要素:边界.最优子结构.状态转移方程. 我们一步步进行解析: 初始化:物品总重量:c=8,物品类别:n=['a','b','c','d'],物品重量:w=[2,4,5,3],物品价值:v=[5,4,6,2] 假设我

[开篇]基础算法和数据结构0

回头想想自己在计算机方法面的知识体系,只能用一盘散沙来总结.决定从这个博客开始,对知识的积累做一次全面的总结,重新想一想自己的职业规划和发展. 这里首先从基本的数据结构开始梳理. 这个先排一下计划. 1.工作和项目的知识梳理和总结 (总结工作这些时间都干了些什么,拿得出哪些东西) 2.个人的规划和方向的重新定位,列出缺陷和不足,列出后面的计划 3.大概建立知识体系的步骤: (1)经典算法的复习和总结: (2)面向对象思维和设计模式: (3)Android体系,重要原理,处理基本问题的方法等.

动态规划算法求解0,1背包问题

首先我们来看看动态规划的四个步骤: 1. 找出最优解的性质,并且刻画其结构特性: 2. 递归的定义最优解: 3. 以自底向上的方式刻画最优值: 4. 根据计算最优值时候得到的信息,构造最优解 其中改进的动态规划算法:备忘录法,是以自顶向下的方式刻画最优值,对于动态规划方法和备忘录方法,两者的使用情况如下: 一般来讲,当一个问题的所有子问题都至少要解一次时,使用动态规划算法比使用备忘录方法好.此时,动态规划算法没有任何多余的计算.同时,对于许多问题,常常可以利用其规则的表格存取方式,减少动态规划算

十大基础实用算法之动态规划

动态规划(Dynamic programming)是一种在数学.计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法. 动态规划常常适用于有重叠子问题和最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法. 动态规划背后的基本思想非常简单.大致上,若要解一个给定问题,我们需要解其不同部分(即子问题),再合并子问题的解以得出原问题的解. 通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量: 一旦某个给定子问题的解已经算出,则将

背包问题:0/1背包问题 普通背包问题(贪心算法只适用于普通背包问题)

//sj和vj分别为第j项物品的体积和价值,W是总体积限制. //V[i,j]表示从前i项{u1,u2,…,un}中取出来的装入体积为j的背包的物品的最大价值. 第一种:0/1背包问题 最大化 ,受限于  1)若i=0或j=0,  V[i,j] = 0 2)若j<si, V[i,j] = V[i-1,j] 3)若i>0且j>=si, V[i,j] = Max{V[i-1,j],V[i-1,j-si]+vi} 第二种:背包问题:在选择物品i装入背包时,可以选择物品i的一部分,而不一定要全部

Java - 冒泡排序的基础算法(尚学堂第七章数组)

/** * 冒泡排序的基础算法 */ import java.util.Arrays; public class TestBubbleSort1 { public static void main(String[] args) { int[] values = { 3, 1, 6, 2, 9, 0, 7, 4, 5, 8 }; int temp = 0; /* 2.调用内循环length-1次,数字逐渐实现从左到右依次向后排, * 每执行n次内循环就出现n个排好的数值,故内循环可少执行i次, 所

有动态示意图!程序员必须知道的10大基础算法讲解

目录: 算法一:快速排序算法 算法二:堆排序算法 算法三:归并排序 算法四:二分查找算法 算法五:BFPRT(线性查找算法) 算法六:DFS(深度优先搜索) 算法七:BFS(广度优先搜索) 算法八:Dijkstra算法 算法九:动态规划算法 算法十:朴素贝叶斯分类算法 算法一:快速排序算法 快速排序是由东尼·霍尔所发展的一种排序算法.在平均状况下,排序 n 个项目要Ο(n log n)次比较.在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见.事实上,快速排序通常明显比其他Ο(n log n