【问题标题】:Variant of rod cutting棒材切割的变体
【发布时间】:2011-11-13 21:29:36
【问题描述】:

给你一根长度为 X 的木棍,上面在任意位置(整体)带有 m 标记,标记表明相应的切割位置。用于切割 L 长度的棍子 分成两块,木匠收费L元(不管两块长度是否相等,即砍价与砍点在哪里无关)。 设计一个动态规划算法来计算最小总成本。

无法确定复发。 在最近的一次编程采访中被问到这个问题。

【问题讨论】:

  • 感觉好像这个问题缺少了什么,可能是一个约束。通常 DP 问题有一个约束,在这个约束下你必须最小化或最大化一个数量。因为如果木棍不需要切割所有标记并且价格与切碎的木材的长度无关,那么只需切割一次,最低价格将是 $L。不确定,如果我错了,可能有人可以纠正我。
  • 所有标记处都需要剪断棍子。

标签: algorithm dynamic-programming


【解决方案1】:

使用 m 个标记,您有 m+2 个有趣的点,0 = 左端点,标记 1,...,m,右端点 = (m+1)。
将兴趣点 0 到兴趣点 i 的距离存储在数组中以计算成本。
编辑:(Doh,无缘无故引入了一个不必要的循环,再次看到 Per 的答案后才注意到)
对于每个0 <= l < r <= m+1,让cost[l][r] 成为在点 l 和 r 之间完全切块的最低成本。解决办法是cost[0][m+1]

// Setup
int pos[m+2];
pos[0] = 0; pos[m+1] = X;
for(i = 1; i <= m; ++i){
    pos[i] = position of i-th mark;
}
int cost[m+2][m+2] = {0};
for(l = 0; l < m; ++l){
    // for pieces with only one mark, there's no choice, cost is length
    cost[l][l+2] = pos[l+2]-pos[l];
}
// Now the dp
for(d = 3; d <= m+1; ++d){  // for increasing numbers of marks between left and right
    for(l = 0; l <= m+1-d; ++l){ // for all pieces needing d-1 cuts
        // what would it cost if we first chop at the left most mark?
        best_found = cost[l+1][l+d];
        for(i = l+2; i < l+d; ++i){ // for all choices of first cut, ssee if it's cheaper
            if (cost[l][i] + cost[i][l+d] < best_found){
                best_found = cost[l][i] + cost[i][l+d];
            }
        }
        // add cost of first chop
        cost[l][i][l+d] = (pos[l+d] - pos[l]) + best_found;
    }
}
return cost[0][m+1];

复杂性:如果您天真地检查所有可能的切碎方法,那就是 m!方法。很坏。 考虑到在任何切割之后,无论是先完全切割左侧部分,然后是右侧部分还是交错切割这两个部分,复杂性(对于 m >= 2)降低到2*3^(m-2)。还是很糟糕。
对于我们的 dp:

  1. 最里面的循环,循环i; d-1 (l
  2. 在 l 上循环:m+2-d (0
  3. 最外层循环,3

好吧,O(m^3) 不是每个人的梦想,但它是我能很快想到的最好的(在 Per 的帖子的一些启发让我注意到之前的低效率之后)。

【讨论】:

  • 无法理解pos[0] = 0; pos[m+1] = X 的必要性。您能否详细说明为什么我们需要这两个额外的点?无论如何,我们不能在这些点切割阵列。
  • 如何在 3 个嵌套 for 循环的最后一条语句中神奇地将成本转换为 3D 数组?
【解决方案2】:

为每一对(标记|端点)计算切割该杆段的最便宜的方法。对于每个段,尽量减少该段中第一次切割的选择。

【讨论】:

    【解决方案3】:

    我猜你想让木匠剪一次,然后一直剪到木棍都剪完,你问的是剪的顺序?

    在这种情况下,一种方法是通过可能的组合树进行深度优先递归搜索,您可以在其中计算成本,记录第一个序列及其成本,然后从那时起,避免下降到成本较高的树中,并始终记录您发现的任何更便宜的序列。

    【讨论】:

    • 我认为您在谈论回溯。这种情况会很昂贵。但面试官正在寻找 DP 解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-05
    • 2014-02-04
    • 1970-01-01
    • 2020-07-04
    • 1970-01-01
    相关资源
    最近更新 更多