问题:
鲍勃计划工作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.
但是,我知道,其中一个,这确实考虑到最佳解决方案可能有两个连续的工作日,而另外两个,我没有建立以前的解决方案。
我的问题:有谁能让我了解这个问题的结构?我觉得我只是不理解使解决方案易于查看的关键属性。
提前致谢!
答案 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决定在第一天工作,则所有其他值均为0
(table[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