动态规划求解0-1背包问题:

问题:背包大小 w,物品个数 n,每个物品的重量与价值分别对应 w[i] 与 v[i],求放入背包中物品的总价值最大。

动态规划核心:计算并存储小问题的最优解,并将这些最优解组合成大问题的最优解。(将原问题分解为若干子问题,然后自底向上,先求解最小的子问题,把结果存储在表格中,再求解大的子问题时,直接从表格中查询小的子问题的解,避免重复计算,从而让提高算法效率)

解决本问题思路:对于第 i 个物品,放入后可以取得最大的价值,那么,前 i-1 个物品在背包容量为 w-w[i] 的情况下能够取到最大的价值。(注:因为第 i 个物品可以放入,对应要占用背包 w[i] 的容量,所以 w-w[i] 的背包容量就是前 i-1 个物品所共有的总容量)

数据结构: value[i][j] 的值表示第 i 个物品放入背包大小为 j 的背包得最大价值。

递归式:

# -*- coding:utf-8 -*-
def main(): w = int(input()) #背包大小
n = int(input()) #物品个数 listWV = [[0,0]]
listTemp = [] for i in range(n):
listTemp = list(map(int, input().split())) #借助临时list每次新增物品对应的list加入到listWV中
listWV.append(listTemp) #依次输入每个物品的重量与价值 # 建立价值数组,初始值均为0,目的是为了在value[0][j]与value[i][0]的情况为0,毕竟不放入物品或者背包容量为0的情况下,背包中的价值肯定为0,
value = [[0 for i in range(w+1)] for j in range(n+1)] for i in range(1, n+1):
for j in range(1, w+1):
if j < listWV[i][0]: #若物品不能放到背包中
value[i][j] = value[i-1][j] #价值与之前相同
else: #物品可以放到背包中,最大价值在两者之中取
value[i][j] = max(value[i-1][j], value[i-1][j-listWV[i][0]]+listWV[i][1]) print(value[n][w]) if __name__ == '__main__':
main()

检测:

10
5
2 6
5 3
4 5
2 4
3 6 17

上述代码只打印了最大价值,若想要打印出分别是那几个物品装入,则:

# -*- coding:utf-8 -*-
def main(): w = int(input()) #背包大小
n = int(input()) #物品个数 listWV = [[0,0]]
listTemp = [] for i in range(n):
listTemp = list(map(int, input().split())) #借助临时list每次新增物品对应的list加入到listWV中
listWV.append(listTemp) #依次输入每个物品的重量与价值 # 建立价值数组,初始值均为0,目的是为了在value[0][j]与value[i][0]的情况为0,毕竟不放入物品或者背包容量为0的情况下,背包中的价值肯定为0,
value = [[0 for i in range(w+1)] for j in range(n+1)] for i in range(1, n+1):
for j in range(1, w+1):
if j < listWV[i][0]: #若物品不能放到背包中
value[i][j] = value[i-1][j] #价值与之前相同
else: #物品可以放到背包中,最大价值在两者之中取
value[i][j] = max(value[i-1][j], value[i-1][j-listWV[i][0]]+listWV[i][1]) print(value[n][w]) #打印放入的物品情况,需要遍历value数组
i = n
j = w
listInfo = [0 for i in range(n+1)]
while i>0:
if value[i][j] > value[i-1][j]: #若在背包容量相同的情况下,后一个物品对应的背包价值大于了前一个物品对应的背包价值,那么说明第i个物品一定放入了背包
listInfo[i] = 1
j = j - listWV[i][0]
i -= 1 listFlag = []
for i in range(len(listInfo)):
if listInfo[i] == 1:
listFlag.append(i) print(listFlag) if __name__ == '__main__':
main()

检测:

10
5
2 6
5 3
4 5
2 4
3 6 17
[1, 3, 5]

0-1背包问题——动态规划求解【Python】的更多相关文章

  1. 01背包问题(动态规划)python实现

    01背包问题(动态规划)python实现 在01背包问题中,在选择是否要把一个物品加到背包中.必须把该物品加进去的子问题的解与不取该物品的子问题的解进行比較,这样的方式形成的问题导致了很多重叠子问题, ...

  2. C++动态规划求解0-1背包问题

    问题描述: 给定n种物品和一背包.物品i的重量是wi,其价值为vi,背包的容量为C.问:应该如何选择装入背包的物品,是的装入背包中物品的总价值最大? 细节须知: 暂无. 算法原理: a.最优子结构性质 ...

  3. Java实现动态规划法求解0/1背包问题

    摘要: 使用动态规划法求解0/1背包问题. 难度: 初级 0/1背包问题的动态规划法求解,前人之述备矣,这里所做的工作,不过是自己根据理解实现了一遍,主要目的还是锻炼思维和编程能力,同时,也是为了增进 ...

  4. 经典递归问题:0,1背包问题 kmp 用遗传算法来解背包问题,hash表,位图法搜索,最长公共子序列

    0,1背包问题:我写笔记风格就是想到哪里写哪里,有很多是旧的也没删除,代码内部可能有很多重复的东西,但是保证能运行出最后效果 '''学点高大上的遗传算法''' '''首先是Np问题的定义: npc:多 ...

  5. 蓝桥杯 0/1背包问题 (java)

      今天第一次接触了0/1背包问题,总结一下,方便以后修改.不对的地方还请大家不啬赐教! 上一个蓝桥杯的例题: 数据规模和约定 代码: import java.util.Scanner; public ...

  6. 背包问题(Knapsack problem)采用动态规划求解

    问题说明: 假设有一个背包的负重最多可达8公斤,而希望在背包中装入负重范围内可得之总价物品,假设是水果好了,水果的编号.单价与重量如下所示:0李子4KGNT$45001苹果5KGNT$57002橘子2 ...

  7. hdu2602Bone Collector ——动态规划(0/1背包问题)

    Problem Description Many years ago , in Teddy’s hometown there was a man who was called “Bone Collec ...

  8. Python动态规划求解最长递增子序列(LIS)

    原始代码错误,移步博客查看O(N^2)及优化的O(N*logN)的实现:每天一道编程题--最长递增子序列

  9. c语言数据结构:01背包问题-------动态规划

    两天的时间都在学习动态规划:小作业(01背包问题:) 数据结构老师布置的这个小作业还真是让人伤头脑,自己实在想不出来了便去网上寻找讲解,看到一篇不错的文章: http://www.cnblogs.co ...

随机推荐

  1. angular ts处理日期格式

    引入DatePipe import {DatePipe} from '@angular/common'; 添加provider @Component({ providers: [DatePipe] } ...

  2. 我是如何同时拿到阿里和腾讯offer的 【转载】

    前言 三月真是一个忙碌的季节,刚刚开学就需要准备各种面试和笔试(鄙视).幸运的是,在长达一个月的面试内推季之后,终于同时拿到了阿里和腾讯的offer,还是挺开心的.突而想起久未更新的博客,就冒昧学一学 ...

  3. 003-结构型-05-桥接模式(Bridge)

    一.概述 将抽象部分与它的具体实现部分分离.使它们都可以独立地变化.通过组合的方式建立两个类之间联系,而不是继承. Bridge 模式又叫做桥接模式,是构造型的设计模式之一.Bridge模式基于类的最 ...

  4. QTableView加载数据

    void VCAdmin::searchAllUser() { strID_Index = ""; if (NULL == vcManageDatabaseObj) { vc_ad ...

  5. VMware Workstation 将虚拟机挂起后,电脑会很卡,SCSI转换成IDE就可以了

    摘自:http://www.360doc.com/content/15/0405/09/10098873_460727712.shtml 用过 VMware Workstation 的人,不知道有没有 ...

  6. centos 7 修改计算机名

      [root@centos7 ~]$ hostnamectl set-hostname test.xyz.com # 使用这个命令会立即生效且重启也生效 [root@centos7 ~]$ host ...

  7. [转]jkeyll的安装步骤

    链接地址:https://nxjniexiao.github.io/2018/08/17/jkeyll-install/

  8. web端自动化——unittest框架编写web测试用例

    1.前言: 对于初学者来说,python自带的IDLE,精简又方便,不过一个好的编辑器能让python编码变得更方便,更加优美些. 不过呢,也可以自己去下载其他更好用的代码编辑器,在这推荐: PyCh ...

  9. RSA算法理解

    RSA加密算法是最常用的非对称加密算法,CFCA在证书服务中离不了它.但是有不少新来的同事对它不太了解,恰好看到一本书中作者用实例对它进行了简化而生动的描述,使得高深的数学理论能够被容易地理解.我们经 ...

  10. JavaScript图形实例:图形的扇形变换和环形变换

    1.1  扇形变换 将如图1所示的上边长方形的图形变换为下边的扇形图形的变换称为扇形变换. 设长方形图形中任一点P1(X1,Y1)变换为扇形图形上的点P2(X2,Y2),长方形的长为X,扇形圆心坐标为 ...