题目描述
牛牛准备参加学校组织的春游, 出发前牛牛准备往背包里装入一些零食, 牛牛的背包容量为w。
牛牛家里一共有n袋零食, 第i袋零食体积为v[i]。
牛牛想知道在总体积不超过背包容量的情况下,他一共有多少种零食放法(总体积为0也算一种放法)。
输入描述:
输入包括两行
第一行为两个正整数n和w(1 <= n <= 30, 1 <= w <= 2 * 10^9),表示零食的数量和背包的容量。
第二行n个正整数v[i](0 <= v[i] <= 10^9),表示每袋零食的体积。
输出描述:
输出一个正整数, 表示牛牛一共有多少种零食放法。
示例1
输入:
3 10
1 2 4
输出:
8
说明:三种零食总体积小于10,于是每种零食有放入和不放入两种情况,一共有222 = 8种情况。
解题思路:
题目看起来和dp算法的背包问题有点相似,该题基本思路也差不多。
第n袋零食是否放入基于上一步每种放入方法的剩余的容量
我自己写了一个遍历的list的方法,但是内存会不足。实在想不到方法解决内存不足了,去看了别人的答案。
本人代码:
a = input().split(' ')
n = int(a[0])
w = int(a[1])
v = list(map(int,input().split(' ')))
li = []
cur_w =w
cnt = 1
li.append(cur_w)
for i in range(1,n+1):
#li[i-1] li[i]
size = len(li)
for j in range(size):
if li[j]-v[i-1]>=0:
li.append(li[j]-v[i-1])
cnt +=1
print(cnt)
别人的代码:
def f(w,v):
if len(v)>0 and v[-1]>=w:
return f(w,v[:-1])
elif sum(v)<=w:
return 2**len(v)
elif w<=0 or len(v)==0:
return 0
else:
return f(w,v[:-1])+f(w-v[-1],v[:-1])
line = input()
n = int(line.split(' ')[0])
w = int(line.split(' ')[1])
line = input()
v = []
for i in range(n):
v.append(int(line.split(' ')[i]))
print(f(w, sorted(v)))
参考思路:
1.对于有大小比较的过程,排序很重要
2.思考是否能将需要list append的方法 转为计算型方法,这里参考 2**len(v) 可大幅度减少内存使用率