当前位置: 首页 > 面试题库 >

获得最佳组合的算法

欧盛
2023-03-14
问题内容

我有ID为的商品1, 3, 4, 5, 6, 7。现在我有如下数据。每行都有一个offerId。Array of IdsID数组中的组合组成。Discount是那个的价值offerId

offerId : Array of Ids     : Discount
o1      : [1]              : 45
o2      : [1 3 4]          : 100
o3      : [3 5]            : 55
o4      : [5]              : 40
o5      : [6]              : 30
o6      : [6 7]            : 20

现在,我必须选择所有给我提供最佳ID组合(即最大总折扣)的offerId。

例如,在上述情况下:可能的结果可能是:

[o2,o4,o5]最大折扣为170(100 + 40 + 30)

注意。结果offerId应该不会重复ID。o2,o4,o6id的示例为[1,3,4],[5],[6]都是不同的。

其他组合可以是: o1, o3, 06其id为[1],[3,5],[6,7],但是总数为120(45 + 55 + 20),170比以前的情况要少。

考虑到每个报价都应包含不同的信息,我需要一个算法/代码来帮助我确定combination of offerIds要给出的maximum discount报价Ids

注意 我正在用go语言编写代码。但是任何语言的解决方案/逻辑都会有所帮助。

注意: 我希望能够正确解释我的要求。如果需要任何其他信息,请发表评论。谢谢。


问题答案:

这是一个动态编程解决方案,它为ID的每个可能子集找到折扣最大的报价组合。这将是伪代码。

让我们的报价成为具有字段的结构offerNumbersetOfItems并且discount。为了实现目的,我们首先通过从零到不同的可能项目数(例如k)减去1
的整数重新枚举可能的项目。之后,我们可以setOfItems用length的二进制数表示k。例如,如果k= 6和setOfItems=
101110 2,则此集合包括项5、3、2 和1,不包括项4和0,因为位5、3、2 和1为1,而位4和0为零。

现在,让我们f[s]成为使用确切s项目集可获得的最佳折扣。在此,s可以是0到2 k -1 之间的任何整数,代表2
k个可能的子集之一。此外,让p[s]我们提供要约清单,这些清单可以使我们共同获得f[s]一组商品的折扣s。该算法如下。

initialize f[0] to zero, p[0] to empty list
initialize f[>0] to minus infinity
initialize bestF to 0, bestP to empty list
for each s from 0 to 2^k - 1:
    for each o in offers:
        if s & o.setOfItems == o.setOfItems:  // o.setOfItems is a subset of s
            if f[s] < f[s - o.setOfItems] + o.discount:  // minus is set subtraction
                f[s] = f[s - o.setOfItems] + o.discount
                p[s] = p[s - o.setOfItems] append o.offerNumber
                if bestF < f[s]:
                    bestF = f[s]
                    bestP = p[s]

之后,bestF是可能的最佳折扣,并且bestP是使我们获得折扣的优惠清单。

复杂度为O(| offers | * 2 k),其中k为项目总数。

这是另一个实现,在渐近上是相同的,但是在大多数子集无法访问时,在实践中可能会更快。它是“向前”动态编程,而不是“向后”动态编程。

initialize f[0] to zero, p[0] to empty list
initialize f[>0] to -1
initialize bestF to 0, bestP to empty list
for each s from 0 to 2^k - 1:
    if f[s] >= 0:  // only for reachable s
        if bestF < f[s]:
            bestF = f[s]
            bestP = p[s]
        for each o in offers:
            if s & o.setOfItems == 0:  // s and o.setOfItems don't intersect
                if f[s + o.setOfItems] < f[s] + o.discount:  // plus is set addition
                    f[s + o.setOfItems] = f[s] + o.discount
                    p[s + o.setOfItems] = p[s] append o.offerNumber


 类似资料:
  • 问题陈述: 我需要得到一个给定数字的最佳面额组合。例如:我有三种面额,给定的数字是30,那么列表应该返回

  • 问题内容: 我如何能够在oracle查询中为几个组获得N个结果。 例如,给定下表: 有更多行和更多职业。我想从每个职业中聘请三名员工(可以说)。 有没有不用子查询就可以做到这一点的方法? 问题答案: 这将产生所需的内容,并且不使用供应商特定的SQL功能(例如TOP N或RANK())。 在此示例中,它为三位雇员提供每个职业emp_id最低的值。您可以更改不等式比较中使用的属性,以使其按名称或其他方

  • 问题内容: 插入行的最佳方法是什么? 我知道和和,但不明白连接到每个利弊。 有人可以解释这些差异以及何时使用它们吗? 问题答案: 返回在所有范围内为当前会话中的任何表生成的最后一个标识值。 您需要小心 ,因为它是跨作用域的。您可以从触发器获取值,而不是当前语句。 返回为当前会话和当前范围中的任何表生成的最后一个标识值。 通常,您要使用什么 。 返回在任何会话和任何作用域中为特定表生成的最后一个标识

  • 我有一个,子数组总是包含5个数字-数字按大小排序,不能在子数组中重复,但是中可以有更多“相同”的子数组(具有相同数字的子数组)。 如何获得数字的组合(数组),其中该组合(或者更确切地说,由该$n数字组合生成的5个数字组合)将与的大多数子数组相匹配? 示例:的的所需结果将是,因为从该结果导出的总共有二十一个5个数字组合: 这些组合将匹配几乎所有的子数组(只有第二个和最后两个子数组超出范围)。 我曾尝

  • 问题内容: 我需要选择一个字段以几个不同的前缀之一开头的行: 在Oracle或SQL Server中使用SQL的最佳方法是什么?我正在寻找类似以下语句的内容(不正确): 或者 编辑:我想看看如何通过在一个SELECT语句中提供所有前缀,或将所有前缀存储在帮助器表中来完成此操作。 前缀长度不固定。 问题答案: 将前缀表与实际表连接将在SQL Server和Oracle中都可以使用。

  • 我正在组装一个java小程序,使任务在工作中更快、更高效。 用户定义项目列表需要拆分成的三个组的大小。列表中的每个项目根据它被放入三个组中的哪个组具有不同的值。小程序需要显示哪个组合的总价值最高。 示例:带有列的二维整数数组;项目编号、第1组中的值、第2组中的值和第3组中的值。 这样,用户定义组1有3个插槽,组2有3个插槽,组3有2个插槽。 小程序应不按特定顺序显示以下解决方案 我可以管理一种效率