0-1背包问题
来源:互联网 发布:淘宝买gtx1080截图 编辑:程序博客网 时间:2024/06/01 08:08
背包问题(Knapsack problem)是一种组合优化的NP完全问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最合适的物品放置于给定背包中。
一般的,0-1背包问题可以描述为1个背包,物品的重量为wi,其价值为vi,背包容量为c。使其价值总量最大。即:
m(i,j)是背包容量为j,可选择物品为i,i+1,…,n时0-1背包问题的最优值。由0-1背包问题的最优子结构性质,可以建立计算m(i,j)的递归式如下:
以上是逆序,即从最满状态一个个扔。如下是顺序的递推式:
为节省空间,可以将二维的列表变为一维的,每次循环只需保留相应位置的较大值即可。
0-1背包问题又可以根据是否恰好放满背包,可以分为两类。首先第一类,就是只要价值最大,质量可以不是刚好最大;第二类则是质量刚好最大,而且价值最大。只需要设置不同的初始化条件,便可以实现不同的答案。
1.对于没有要求必须安装背包的情况下,初始化最大值都为0,是不存在非法状态的。因为可以什么都不装。2.但是如果要求恰好装满,则必须区别初始化,即f[0]=0,其他设为一个较大的负数。以下以例题进行讲解:
题目描述:
小白和小红一起逃亡,现在有许多的东西要放在小红的包里面,但是包的大小有限,所以我们只能够往里面放入非常重要的物品。现在给出该种物品的数量、体积、价值的数值,希望你能够算出怎样使背包的价值最大的组合方式,并输出这个值。
输入:
第一行有2个整数,物品种数n和背包装载体积v
第二行到i+1行每行3个整数,为第i种物品的数量m、体积w、价值s
输出:
一个整数,整数表示最大价值。
解析:
这题没有恰好,所以,初始化都为0即可,这里我用两种代码形式表示,一种是逆序的递推,一种顺序的递推:
代码实现:
1.逆序:
#-*-coding:utf-8 -*-while True: try: n,v=map(int,raw_input().split()) we,se=[0],[0] res=[] t=[] q=[] r=0 for i in range(n): m,w,s=map(int,raw_input().split()) r+=m we.extend([w]*m) se.extend([s]*m) dp=[[0 for i in range(v+1)] for j in range(r+1)] for j in range(v + 1): if j >= we[r]: dp[r][j] = se[r] else: dp[r][j] = 0 for i in range(r-1,-1,-1): for j in range(v+1): if j<we[i]: dp[i][j]=dp[i+1][j] else: dp[i][j]=max(dp[i+1][j],dp[i+1][j-we[i]]+se[i]) print dp[0][-1] except: break
顺序:
def solve(v,w,s,n): r = [0]*(s+1) r[0]=0 for i in range(1,n+1): for j in range(s,0,-1): if w[i] <= j: r[j] = max(r[j],r[j-w[i]]+v[i]) return r[-1]if __name__ == '__main__': n,weight=map(int,raw_input().split()) we=[0] se=[0] r=0 for i in range(n): m, w, s = map(int, raw_input().split()) r += m we.extend([w] * m) se.extend([s] * m) result = solve(se,we,weight,r) print(result)
ps:这两个都在we和se数组最开始加了0,为了平衡数组的下标。
2.假如是恰好呢?
def solve2(v,w,s,n): r = [-100]*(s+1) r[0]=0 for i in range(1,n+1): for j in range(s,0,-1): if w[i] <= j: r[j] = max(r[j],r[j-w[i]]+v[i]) return r[-1]if __name__ == '__main__': n,weight=map(int,raw_input().split()) we=[0] se=[0] r=0 for i in range(n): m, w, s = map(int, raw_input().split()) r += m we.extend([w] * m) se.extend([s] * m) result = solve2(se,we,weight,r) print(result)
转载请注明:转自http://blog.csdn.net/carson0408/article/details/77825391
- 背包问题(0-1背包、完全背包、多重背包)详解
- 背包问题和0-1背包问题
- 背包问题和0-1背包问题
- 背包问题系列--"0-1背包问题"
- 背包笔记-含0/1背包问题、完全背包问题、多重背包问题、二维背包问题、分组背包问题
- 【背包问题】背包问题之0-1背包、完全背包、多重背包
- 0-1背包问题
- 0/1背包问题
- 0,1背包问题
- 0-1背包问题
- 0/1背包问题
- 0-1背包问题
- // 0-1背包问题
- 0/1背包问题
- 0-1背包问题
- 0-1背包问题
- 0-1背包问题
- 0/1背包问题
- 超简单!Linux下FTP服务器的安装和配置(基于Ubuntu)
- HDU 5877 Weak Pair (dfs 树状数组 || dfs序 主席树)
- svm+hog 训练,检测手写数字
- Asp.net MVC中ViewData与ViewBag的使用方法
- MySQL半同步复制--RUN_HOOK
- 0-1背包问题
- tomcat+nginx+redis实现均衡负载、session共享(二)
- 损失函数
- HDU -- 6188 Duizi and Shunzi 【思维】
- 33 Three.js的材质THREE.MeshBasicMaterial
- 自定义View实现视差特效
- 校招上机题(收集)
- QT笔记
- ajax和json