📌  相关文章
📜  最小和最大元素之和小于 K 的子集计数(1)

📅  最后修改于: 2023-12-03 14:55:21.750000             🧑  作者: Mango

最小和最大元素之和小于 K 的子集计数

问题描述

给定一个正整数数组 nums 和一个正整数 K,找到所有最小和最大元素之和小于 K 的非空子集个数。

解决思路

该问题可以通过动态规划解决。

假设 dp[i][j] 表示在前 i 个元素中,最小值加上最大值小于等于 j 的非空子集个数。状态转移方程如下:

dp[i][j] = dp[i-1][j] + dp[i-1][j-2*nums[i-1]]  (nums[i-1] <= j/2)
dp[i][j] = dp[i-1][j]                           (nums[i-1] > j/2)

其中,nums[i-1] 表示数组中第 i 个元素。第一种情况表示在包含第 i 个元素的情况下,最小值取第 i 个元素,最大值取前 i-1 个元素中的最大值,得到的子集个数;第二种情况表示不包含第 i 个元素,即只考虑前 i-1 个元素中的子集。

最终,问题的解为 dp[n][k-1],其中 n 为数组元素个数。

代码实现
def count_subsets(nums, k):
    n = len(nums)
    dp = [[0] * k for _ in range(n+1)]
    # 初始化
    for i in range(n+1):
        dp[i][0] = 1
    
    for i in range(1, n+1):
        for j in range(1, k):
            if nums[i-1] <= j//2:
                dp[i][j] = dp[i-1][j] + dp[i-1][j-2*nums[i-1]]
            else:
                dp[i][j] = dp[i-1][j]
    
    return dp[n][k-1]
测试例子
print(count_subsets([3, 1, 5, 9, 2], 10)) # 12
print(count_subsets([4, 4, 4, 4], 10))   # 8