Written with StackEdit.
给定 C C C, ( w i , v i ) (w_i,v_i) (wi,vi)求 m a x ∑ x i v i ≤ C , x i ∈ I n t e r v a l max\sum x_iv_i\leq C,x_i\in\ Interval max∑xivi≤C,xi∈ Interval
0-1是最简单的背包问题,这里 i n t e r v a l ∈ { 0 , 1 } interval\in \{0,1\} interval∈{0,1}
设 P ( i , w ) P(i,w) P(i,w)为在序列前i个中选取总重不超过w的,使得权值最大. 则 ∀ i , w , P ( i , w ) = M a x { P ( i − 1 , w ) , P ( i − 1 , w − w i ) + v i } \forall i,w,\\P(i,w)=Max\{P(i-1,w),P(i-1,w-w_i)+v_i\} ∀i,w,P(i,w)=Max{P(i−1,w),P(i−1,w−wi)+vi} 也就是是否选入第i个.
很简单,直接按照状态转移填. 虽然会爆栈hhhhh
构建二维矩阵: 行是前i个元素 列是限制的重量 扫描方式是逐行扫描记忆化.
输入:
总重量限制重量序列价值序列输出: 最大价值
记忆化搜索.横向扫描填表. 注意可以忽略weight=0的一列,初始化置为0.
''' @Description: 改进,非递归 @Date: 2019-10-31 11:39:57 @Author: I-Hsien @LastEditors: I-Hsien @LastEditTime: 2019-10-31 12:11:50 ''' import numpy as np def build(set,maxop:int): table=np.zeros((len(set),maxop+1))# An empty table for i in range(len(set)): for j in range(1,maxop+1):#[1]-[maxop] if set[i][0]>j: table[i][j]=table[i-1][j] else: table[i][j]=max(table[i-1][j],table[i-1][j-set[i][0]]+set[i][1]) #print("max in",table[i-1][j],table[i-1][j-set[i][0]]+set[i][1]) #print("set",i,j,table[i][j]) #print(table) return table[-1][-1] if __name__=="__main__": maxround=(input().split()) maxweight=int(maxround[0])#C round=int(maxround[1]) setop=[]#int list for _ in range(round): temp=input().split() setop.append((int(temp[0]),int(temp[1])))#[(weight,value)] print(int(build(setop,maxweight)))明显的存在大量无用数据,在limit很大时内存占用过大.优化方法参见https://zhuanlan.zhihu.com/p/30959069,暂且留一个坑在这…