DP - 查找具有一组特定规则的数组的最大总和

时间:2015-01-10 19:18:04

标签: algorithm dynamic-programming

这是关于我刚刚接受SE实习计划面试时收到的特定DP问题/问题。我无法找到适合它的解决方案,因此它一直困扰着我。一线希望是我意识到我需要处理我的DP技术。

所以,问题是这样的: -

给定一个数组n(即[1, 5, 0]和一组大小为n + 1的节点(在这种情况下,会有4个节点),这些节点需要以这种方式排列,以便找到可以从这种节点排列中提取的最大值。给定的标准如下: -

  • 数组中的每个位置/索引表示当前节点可以连接的其他节点的数量;即第一个索引意味着一个节点连接到另一个节点,第二个意味着一个节点连接到另外两个节点,依此类推。依此类推。
  • 数组中的每个值表示如果节点连接到一个,两个,三个......,(n-1)个其他节点,您可以提取多少增益。因此,如果一个节点连接到另一个节点,则提取的值(在这种情况下)将为1(根据上面的数组)。
  • 这些节点的排列不能是循环的。即X1 -- X2 -- X3 -- X4是可以接受的。

我认为一些例子有助于更好地了解问题领域: -

输入:[1, 5, 0] |预期输出:12 |预期的节点排列:X -- X -- X -- X

说明: - 总共有4个节点,输入表示如果一个节点与其他一个节点连接,则该节点将产生1个单位的值/增益,如果它与其他2个节点直接连接,则为5个单位,没有值/如果它与其他3个节点直接连接,则获得所有权利。在最佳设置(如上所示)中,第一个和最后一个节点每个产生1个单元(每个节点连接到另一个节点),而序列中间的两个节点每个产生5个单元的节点。因此,可收集的最大值/增益为1 + 5 + 5 + 1 = 12。

输入[0, 0, 0, 0, 50] |预期输出:50 |预期的节点排列:*考虑STAR形状,中间有(n+1)节点,因为如果节点连接到其他5个节点,则增益为50。

输入[1, 2, 3, 4, 5, 6] |预期输出:12

输入[3, 9, 6, 15, 9, 21, 15] |预期输出:60

如果您不理解给定的问题/给出的示例,请随时提出问题,我会尽力澄清问题。

正如我所说的那样,我正处于改善DP特定问题的过程中。所以,我不希望在这里给出完整的解决方案。我只是要求提示/线索/我可以开展工作的起点。审查的算法也足够了!

基本上,任何帮助将不胜感激。提前致谢! :)

1 个答案:

答案 0 :(得分:0)

事实上,它类似于在n个顶点上生成所有不同的非同构树,然后找到可以从节点排列中提取的最大值的问题。

订单n的非同构树数量 1 1 1 2 < / strong>, 3 6 11 23 47 ,<强> 106 235 551 1301 3159 ,...(OEIS A000055 )具有生成函数但没有已知的闭合公式。

The trees with up to six nodes

根据degree序列,这​​可以用以下列表表示。

例如,对于n = 6

[1,2,2,2,2,1]

[1,2,2,3,1,1]

[1,2,3,1,2,1]

[1,2,4,1,1,1]

[1,1,1,1,1,5]

[1,3,1,1,3,1]

但是,在我们的例子中,[1, 2, 2, 3, 1, 1][1, 2, 3, 1, 2, 1]都代表1(3), 2(2), 3(1)(一个节点有三个顶点+两个节点有两个顶点+三个节点有一个顶点)。因此,我们可以丢弃所有重复的项目,并以反向词典顺序生成以下无序序列:

[5,1,1,1,1,1]

[4,2,1,1,1,1]

[3,3,1,1,1,1]

[2,3,2,1,1,1]

[2,2,2,2,1,1]

我们可以说:

  1. 在具有n个顶点(如上面的树)的连接树中,每个顶点 degree至少为n-1,最多为S
  2. 树的度序列的大小C= 2(n-1)与顶点的数量相同(很明显!)。
  3. 所有顶点degrees的总和:n(例如,对于n = 6,C = 10)。
  4. 问题:对于n-1个节点,我们有ith个节点类型,其中di项类型的度数为vi,值为D。我们正在尝试使用总容量C和大小S填充度数序列D,并选择最大值项。我们可以向Integer Knapsack Problem添加多个相同类型的项目。 这与C(允许的重复项目)存在类似的问题,但存在一些限制:总体权重必须等于S,项目数量必须< / strong>等于n = 4

    示例: 3

    我们有[1, 2, 3]种类型的节点(度):[1, 5, 0]具有给定值:4 序列的大小(背包)是:6,它的容量= Let us initialize a 3-d array arr[i][j][k] to “unknown” for all i,j,k. Value(n,C,S) { if (S == 0) return 0; //No more Space else if (S > C || S * n < C) return INT_MIN; //impossible to fill! if (n == 0) return 0; //No more item if (arr[n][C][S] != unknown) return arr[n][C][S]; if (n > C) result = Value(n-1,C,S); // can’t use nth item else if(n == C && S > 1) result = Value(n-1,C,S); // can't use it, if we do, we won't have enough capacity to fill the spaces else { for(int i = n - 1; i > 0; i--) q = max{q, P[i] + Value(i, C - i, S - 1)} // P[i] = value of a node with a degree of i result = max{q, Value(n - 1, C, S)}; } arr[n][C][S] = result; return result; }

    DP解决方案

    {{1}}