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

从平衡子集和有效地跟踪集的和?

唐弘厚
2023-03-14

平衡子集和问题被描述为将阵列分成两个子集,使得两个子集和的差最小,最好的情况是两个子集和相等。

注意:-我们不能离开原始集合中的元素。

现在,我需要得到最小差分划分的集合1和集合2的和,我已经使用O(sum*sum*n)解决方案找到了集合的和,但为了我所做的工作,我需要一些复杂度更好的东西。如何在比O(sum*sum*n)更短的时间内解决这个问题?

我的 O(N^3) 方法如下: 注意:-s1,s2,s3 是静态变量,总和是数组的总和。

static int partition(int sum1, int sum2, ArrayList < Integer > arr, int i) {
 if (i == arr.size()) {
  if (Math.abs(sum1 - sum2) < s3) {
   s1 = sum1;
   s2 = sum2;
   s3 = Math.abs(sum1 - sum2);
  }

  return Math.abs(sum1 - sum2);

 }
 if (dp[(sum1 < 0) ? 2 * sum - sum1 : sum1][(sum1 < 0) ? 2 * sum - sum1 : sum1][i] != 0)
  return dp[(sum1 < 0) ? 2 * sum - sum1 : sum1][(sum1 < 0) ? 2 * sum - sum1 : sum1][i] > 0 ? dp[(sum1 < 0) ? 2 * sum - sum1 : sum1][(sum1 < 0) ? 2 * sum - sum1 : sum1][i] - 1 : dp[(sum1 < 0) ? 2 * sum - sum1 : sum1][(sum1 < 0) ? 2 * sum - sum1 : sum1][i];


 int c1 = partition(sum1 +  arr.get(i), sum2, arr, i + 1);
 int c2 = partition(sum1, sum2 +  arr.get(i), arr, i + 1);

 if (Math.abs(c1) < Math.abs(c2)) {
  dp[(sum1 < 0) ? 2 * sum - sum1 : sum1][(sum1 < 0) ? 2 * sum - sum1 : sum1][i] = c1 >= 0 ? c1 + 1 : c1;
  return c1;
 } else {
  dp[(sum1 < 0) ? 2* sum - sum1 : sum1][(sum1 < 0) ? 2 * sum - sum1 : sum1][i] = c2 >= 0 ? c2 + 1 : c2;
  return c2;
 }

}

共有1个答案

谭云瀚
2023-03-14

我认为您应该使用在O(sum*n)中运行的伪多项式算法,尽管注释中建议使用O(2^n)蛮力方法也应该有效。

这个想法类似于背包的伪多项式算法:找到所有组合值小于或等于MAX=sum/2的可能分区。这些分区中最大的将是您正在寻找的分区。

下面是一个可能的python实现:

def min_partition_diff(items):
    summed=sum(items)
    MAX=summed//2


    value_reachable=[False]*(MAX+1)    
    value_reachable[0]=True #at the beginning only the empty set with value 0 is reachable

    #update all possible configurations:
    for item in items:
        for i in reversed(range(MAX)):# //backwards->object at most once in every configuration!
            if value_reachable[i]:#update configuration only if it can be constructed with earlier items
               next_reachable_value = i+item
               if next_reachable_value <= MAX:
                    value_reachable[next_reachable_value]=True

    biggest_value_possible=MAX - value_reachable[::-1].index(True)# find last True in the values

    return summed-2*biggest_value_possible # this is the smallest difference
 类似资料:
  • 本章展示如何配置Istio来自动收集mesh中服务的遥测数据。 在本章末尾,将为mesh中的服务调用启用新的metric和新的日志流。 BookInfo应用将作为介绍本章内容的示例应用。 开始之前 在集群中安装Istio并部署一个应用程序。 本章假设Mixer使用默认配置(--configDefaultNamespace=istio-system)。 如果使用不同的值,则更新这个任务中的配置和命令

  • 本章介绍如何配置istio去自动收集mesh中的TCP服务指标。本章结尾部分,一个新的监控指标可以用mesh去调用TCP服务。 BookInfo应用作为介绍本章的示例应用。 开始之前 在集群中安装istio并部署一个应用。 本章假定BookInfo中的示例应用被部署在default命名空间中。如果部署在不同的命名空间,你需要修改例子中的配置和命令。 安装Prometheus插件,Prometheu

  • 我试图了解C程序在汇编级别上的样子,所以我运行gdb并在主get_input上使用反汇编。该程序很短,因此我可以更好地遵循它。有2行我不明白。在 main() 中的第一个是:

  • 我正在解决“破解编码面试”中的以下问题:实现一个函数来检查二叉树是否平衡。平衡树是这样一种树:任何节点的两个子树的高度相差不会超过一个。 这本书的示例解决方案(复制如下)假设从节点发出的树是平衡的,如果(a)节点的左子树和右子树是平衡的;和(b)节点本身是平衡的。我在试图理解为什么会这样?以上两个条件的满足如何证明从节点发出的整个树是平衡的? 谢啦

  • 我是Spring Integration framework的新手,希望使用它跟踪应用服务器中的java日志文件,逐行分组,直到获得完整的stacktrace,然后将StackTraces发送到另一个应用程序。我使用(int file:tail-inbound-channel-adapter)成功地跟踪了文件,但我不知道要使用哪个spring集成组件来对(int file:tail-inbound

  • 假设我在一个集群中有3个ActiveMQ Artemis代理: 经纪人_01 在给定的时间点,我有每个经纪人的消费者数量: 经纪人有50名消费者 让我们假设在这个给定的时间点,有70条消息要发送到集群中的一个队列。 我们期望集群完成负载平衡,以便Broker_01将接收50条消息,Broker_0210条消息,Broker_0310条消息,但目前我们正在经历70条消息通过所有3个代理随机分发。 是