给定一个整数数组,求使用数组中的数加和得到目标值的所有方案数——python动态规划实现

题目描述

  • 第一行输入一个整数N代表物品数量,第二行输入N个正整数代表每个物品的价值。每个物品不可分割,不能以部分价值分配。问:若要把这些物品等价值的分配给两个人,分配方案的数量是多少?若无法达到分配要求,则输出’No solution!‘(样例如下)
  • input:
    • 5
    • 1 2 2 3 4
  • output:
    • 4

python实现

from functools import reduce
def fangan(li):
    num = reduce(lambda x,y:x+y, li) # 计算数组总和
    if num % 2 == 1: # 平分给两个人,物品价值一定为偶数。若为奇数,则直接输出无解
        return 'No solution!'
    target = num // 2 # 平分给两个人,所以每个人能得到的目标值是数组和的一半
    s_num= len(li) # 获取物品数量,直接在函数里传入输入n也可
    dp = [[0] * (target + 1) for _ in range(s_num+ 1)] # 构建
    dp[0] = [0] * len(dp[0])  # 初始化二维数组第0行
    for i in range(len(dp)):
        dp[i][0] = 1  # 初始化二维数组第0列,实现0价值的分配有且仅有一种方案
    for i in range(1, s_num+1):
        for j in range(1, target+1):
        	# 如果当前价值数j足够放进当前物品(i-1)的价值,那么dp[i][j]的值为不放当前物品达到j的方案数dp[i-1][j] + 
        	# 放进当前物品达到j的方案数dp[i-1][j-li[i-1]]
        	# 因为二维数组是s_num + 1行的,所以li[i-1]表示当前的物品价值,而不是li[i]
            dp[i][j] = dp[i-1][j] + dp[i-1][j - li[i-1]] if j - li[i-1] >= 0 else dp[i-1][j]
    return dp[-1][-1]

n = int(input())
stuffs = list(map(int, input().split(' ')))
print(fangan(stuffs))
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值