01背包问题求方案数

背包问题求方案数
该题为01背包的延伸,需要添加一个记录数组:

def ZeroOneBagCount(N, V, v, w):
    memo = [0 for i in range(V+1)]  ## 备忘录数组
    count = [1 for i in range(V+1)]  ## 增加一个计数数组(每种容量都至少有一种方案)
    mod = 10**9+7
    for i in range(N):
        for j in range(V,v[i]-1,-1):   ## 从最大容量开始向前循环到当前物品需要的最小容量(比v[i]小的容量再循环下去也没有意义)
            if(memo[j] == memo[j-v[i]]+w[i]):  
                count[j] += count[j-v[i]]      ## 若两者相等,则方案数为当前位置数加上剩余背包容量的方案数
            elif(memo[j] < memo[j-v[i]]+w[i]):
                count[j] = count[j-v[i]]       ## 若不相等,则方案数和上一层方案数相等
            memo[j] = max(memo[j], memo[j-v[i]]+w[i]) ## 更新备忘录数组中当前容量的最大价值
        print(count)
    print(count[-1]%mod)
N, V = map(int,input().split())
v, w = [], []         ## v为容量数组,w为价值数组
for i in range(N):
    a, b = map(int, input().split())
    v.append(a); w.append(b)

ZeroOneBagCount(N, V, v, w)

值得注意的是{ count[ j ] += count[ j - v [ i ]] } 和 { count[ j ] = count[ j - v [ i ]] } ,因为当前count[ j ] 与上一个物品的在不同背包容量的方案数有关,所以这么写,一定要注意!!!(j 是从最大到小循环,所以在 j 位置之前的count和memo都还是没更新上一个物品的记录)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值