【刷题日记】网易——牛牛的背包问题

牛牛准备参加学校组织的春游, 出发前牛牛准备往背包里装入一些零食, 牛牛的背包容量为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

输出例子1:

8

例子说明1:

三种零食总体积小于10,于是每种零食有放入和不放入两种情况,一共有222 = 8种情况。

# python 2.7
line = raw_input()
n = int(line.strip().split(' ')[0])
w = int(line.strip().split(' ')[1])
v = []
line = raw_input()
for j in range(n):
    v.append(int(line.strip().split(' ')[j]))

def main():
    for k in range(len(v)+1): # 放0~n件零食
        dfs(v,0,k)

def dfs(v,vol,k):
	# 递归终止条件
	# 1. 放入零食已超过容积:无效放法,直接返回
	# 2. 放入k件,还没有超过容积,有效放法,放法+1
    global ans
    if k>0 and vol > w: #k>0:还要放入,vol>W :体积已经超过背包容量
        return
    if k==0: # 如果已经放入k件
        if vol <= w: # 体积没有超过容量
            ans += 1 # 该放法有效,总方法数+1
        return
    # 递归
    # 每次放入一件物品,考察后面的物品放入放法还有多少种
    # 为了不重复,只考察当前放入的第i件物品之后的物品
    for i in range(len(v)): # 放入第i件,剩余k-1件还有几种放法
        dfs(v[i+1:],vol+v[i],k-1)

# 如果零食体积没有超过背包容量,则一共2^n次方
if sum(v)<= w:
    print 2**n
else:
# 如果超过了,则递归计算
    ans = 0
    main()
    print ans

你可能感兴趣的:(刷题日记)