当前位置: 首页 > 知识库问答 >
问题:

子集和变化

尚俊楠
2023-03-14

给定一个不同大小的整数< code>n和< code>s集合,但元素为从< code>0到< code>s_i的正升序数字。让一个好的和在这里被定义为...a_s = n。当您从对应的集合< code>s_i中为每个< code>a_i取一个元素时,计算存在多少个和。

我试图生成任何可能的方法并省略那些可省略的方法,即当你有例如 s=3n=1 并且你得到集合 s_0={0,1}, s_1={0,1,2,3}, s_2={0,1,2},然后你可以省略对总和 0 0 a_3的检查,因为a_3不能足够大。我已经为每个可能的序列应用了动态编程解决方案来计算正常子集和,但是,我得到的结果比我应该得到的要大得多,而且速度也很慢。

有什么好的算法可以在这里应用吗?

共有1个答案

陆曜文
2023-03-14

通过使用两个字典(数组也可以工作,但字典更好),您可以在经典子集和解决方案上实现轻微的变化:

dp[i] = dictionary of sums we can obtain using the first i sets and their counts


dp[0, <elements in s[0]>] = 1
for i = 1 to s - 1:
  for each element x in dp[i - 1]:
    for each element k in s[i]:
      dp[i, x + k] += dp[i - 1, x]

复杂性会很大,但我认为你无能为力来降低它。不过它应该可以工作。

你可以只在内存中保存两本字典,因为你只需要当前的和以前的。

Python代码:

def solve(s, n):

    dp = [dict()] * len(s)

    for k in s[0]:
        dp[0][k] = 1
    for i in range(1, len(s)):
        dp[i] = dict()
        for x in dp[i - 1]:
            for k in s[i]:
                if x + k in dp[i]:
                    dp[i][x + k] += dp[i - 1][x]
                else:
                    dp[i][x + k] = dp[i - 1][x]

    return dp[len(s) - 1][n]

print(solve([[0,1,2],[0,1,2]], 3)) # prints 2
print(solve([[0,1,2],[0,1,2,3,4],[0,1,2,3,4]], 5)) # prints 13
 类似资料:
  • 我试图获取当前类包装器的可变参数子集,以实例化一个新的变量 目前我有: 我想实现以下目标: 您可以假设每个类型在变量类中只存在一次,并且我将始终请求当前变量类型的子集。我不知道这在C11中是否可行?谢谢你的帮助。

  • 我想计算一个集合S存在多少对不相交的子集S1和S2(S1 U S2可能不是S),其中S1中的元素和=S2中的元素和。 假设我已经计算了所有可能的2^n子集的所有子集和。我如何找到有多少不相交的子集有相等的和。 对于一个和值a,我们能用有和a/2的子集的计数来解决这个问题吗? 例如:S={1,2,3,4} 以下是问题的链接:http://www.usaco.org/index.php?page=vi

  • 我创建了一个新示例,并将代码分为客户端和服务器端。 完整的代码可以在这里找到。 服务器端有3个版本。 服务器无Spring Boot应用程序,使用Spring Integration RSocket InboundGateway 服务器引导重用Spring RSocket autconfiguration,并通过serverrsocketmessagehandler创建ServerRSocketC

  • 问题内容: 我正在尝试编写一个函数,该函数不仅将确定集合的子集的总和是否会增加到所需的目标数量,而且还将打印解决方案的子集。 这是我的代码,用于查找是否存在子集: 如何修改它以记录子集本身,以便可以打印它?提前致谢! 问题答案: 根据您的解决方案:

  • 问题内容: 我正在张量流中训练一个生成对抗网络(GAN),基本上我们有两个不同的网络,每个网络都有自己的优化器。 问题是我先训练一个网络(g),然后再一起训练g和d。但是,当我调用load函数时: 我有这样的错误(回溯很多): 我可以恢复g网络并继续使用该功能进行训练,但是当我想从头开始盯着d并从存储的模型中盯着g时,我会遇到该错误。 问题答案: 要还原变量的子集,您必须创建一个新变量并将变量的特

  • 当我遇到这个问题时,我正在温习动态编程。我设法用DP来确定子集和问题有多少解。 基于子集总和-恢复解决方案,我使用以下方法来检索子集,因为该集将始终被排序: 但是,由于它是一种贪婪的方法,因此它仅在每个子集的最大元素不同时才有效。如果两个子集具有相同的 max 元素,则它只返回具有较大值的子集。因此,对于总和为 10 的元素 [1, 2, 3, 4, 5],它只返回 当它应该回来的时候 我可以在w

  • 我有一个子集问题的工作代码,如果它发现一个子集等于所需的目标,它可以打印数字。 > 我想打印给定目标的所有可能的子集,我不知道要为此更改什么。 我如何让它对负数起作用?

  • 我知道这是子集和问题的一个变体,我也见过类似问题的一些解决方案(带负数的子集和),但我需要用动态规划来解决这个问题。我见过的大多数解决方案都使用递归,而不是DP。 我想我需要一个大小为(n*n*d)的3d布尔表S(I,j,k)。但是S(i,j,k)什么时候为真,什么时候为假?因为我总是需要检查使用k个数计算和的所有可能方法,这些方法既可以是正数,也可以是负数(例如:对于4个数{1,2,3,4},有