动态编程:每日任务,最大利润调度

时间:2016-05-17 13:33:34

标签: python algorithm dynamic-programming

问题:

鲍勃计划工作n天,i每天都有一个任务;每个任务只持续一天,必须在给出的i天完成,并支付bob x_i美元。鲍勃一次不能连续工作5次以上。也就是说,他必须每5天至少休息一天。

Given号码x_1...x_n,Bob应该在哪些日子执行任务,以及他应该在哪几天休息,以便赚取尽可能多的钱而且工作时间不超过5天?您的解决方案应为O(n)

我的问题:

我无法解决此问题的再次发生。我一直在考虑这个问题很长一段时间。我最初的想法是让p[i] = max{x_i + x_i-1 + .... + x_i-4}, where p[i] is the max profit earnable from days i-4 to i.但是,我知道,其中一个,这确实考虑到最佳解决方案可能有两个连续的工作日,而另外两个,我没有建立以前的解决方案。

我的问题:有谁能让我了解这个问题的结构?我觉得我只是不理解使解决方案易于查看的关键属性。

提前致谢!

4 个答案:

答案 0 :(得分:1)

每天我可以选择工作和减少剩余工作日数1并获得x_i或休息并将您的可用工作日重置为5,在基础情况下,您在第0天连续工作5天

if (remaining_rest_days == 0) {
    MaximumProfit(current_day, 0, current_profit) = MaximumProfit(current_day+1, 5, current_profit)
} else {
    MaximumProfit(current_day, remaining_rest_days, current_profit) = 
    max(
        MaximumProfit(current_day+1, remaining_rest_days - 1, current_profits + profit[current_day]),
        MaximumProfit(current_day+1, 5, current_profits)
    )
}

答案 1 :(得分:1)

动态构建维度6 x n的表格。条目table[w_i][d_j]将表示Bob连续工作i天(包括今天)并且为j天的最大可达值。

第一栏很容易填写: table[1][0] = x_0如果Bob决定在第一天工作,则所有其他值均为0table[0][0] => Bob在第一天无效,table[2..5][0] =&gt ; Bob在第1天连续几天无法工作。)

根据以下规则继续逐列完成表格:

连续j天工作的0天的最大值是前一天的任何值的最大值,并且今天不起作用: table[0][d_j] = max{ table[0..5][d_j-1] }

连续工作日j天的1天的最大值是前两天的最大值,没有连续工作天数加上x_j。 (休息超过2天是没有意义的,因为我们可以在两天之间工作。):

table[1][d_j] = max{ table[0][d_j-2], table[0][d_j-1] } + x[d_j]

否则,table[w_i][d_j] = table[w_i-1][d_j-1] + x[d_j]

解决方案将是最后一列中的最大值。

答案 2 :(得分:1)

我将公式定义如下:

  

P(d,i):= d天,您已连续工作i天(包括第d天),您可以获得的最高金额

对于基础案例P(1,1) = x_1,其他人为0, 然后答案是max(P(n,0), P(n,1)...P(n,5))

公式是

P(d,0) = max(P(d-1,0), P(d-1,1)...P(d-1,5))
P(d,1) = P(d-1,0) + x_d
P(d,2) = P(d-1,1) + x_d
...
P(d,5) = P(d-1,4) + x_d

显然可以使用O(n)

的单个循环来完成

我对该公式的推理是,对于P(d,i) where i>=1,这意味着您在d天工作,并且当您已连续i天工作时,前一个i-1你必须工作的日子,因此公式P(d-1, i-1) + x_d

对于P(d,0),这意味着您在第d天休息,您也可以在前几天休息,但最多5天,否则它不一定是最佳解决方案(有意义) ?),因此公式P(d,0) = max(P(d,i)) for i in [0,5]

答案 3 :(得分:0)

我真的很感激这里发布的所有解决方案。我能够提出解决方案,所以我想我会发布它。请注意,此解决方案仅返回最大利润,而不是任何特定日期。

Let P[i] = the maximum expected profit from day 1...i if Bob rests on day i

Recurrence: P[i] = max{p[j] + x_j+1 + x_j+2 + ... + x_i-1, for i - 6 <= j < i因此,我们希望P[i]是bob在i日休息时连续五天连续工作的总和,加上他本可以获得的利润到最后一个休息日j

<强>代码:

def get_best_missions(x):

    n = len(x)

    p = [0 for i in range(n)]

    for i in range(1,n):
        j = i - 6

        if j < 0:
            p[i] = sum(x[0:i])
        else:
            p[i] = max(p[i], p[j] + x[j+1] + x[j+2] + x[j+3] + x[j+4] + x[i - 1])

    return max(p)

示例&amp;结果

x = [10, 10, 10, 5, 20, 10, 5]
best = get_best_missions(x)

p = [0, 10, 20, 30, 35, 55, 55]
best = 55