选择要做哪些任务以赚取尽可能多的钱

时间:2015-02-14 20:26:16

标签: algorithm time-complexity

我无法理解这个问题:

  • 您已获得 n 任务
  • 每个任务的时间 t ,表示完成任务所需的时间 t [i] 是< strong> i -th task)
  • r [i] 表示 i -th任务的截止日期(我们从时间= 0开始, r [ i] 是一个表示必须完成任务的int)
  • 如果任务在截止日期之前完成,您将获得奖励 p [i] 任务
  • 你需要计算你可以通过结合这些任务获得的最大奖励
  • 只有在符合截止日期时才会给予奖励
  • 所有值均为整数
  • 解决方案必须是最低复杂度可能

我尝试应用贪心方法,但我意识到算法并不总能给出最优解。我可以写一个蛮力算法,但这不是重点。我认为可以使用动态编程,但我不知道如何。

2 个答案:

答案 0 :(得分:3)

如果所有时间都相等,则系统可以显示为拟阵,贪婪算法将得到最佳结果(参见第34章&#34;算法导论&#34;作者Charles E. Leiserson,Thomas H. Cormen,Clifford Stein和Ronald Rivest)。

但是,假设时间不相等,一般情况下这个问题是NP难的。

要了解原因,请考虑所有截止日期都是固定值的情况。那么问题就等于找到将项目打包到固定时间预算中的最佳方法,并且相当于已知为NP完全的knapsack problem

在您的特定情况下,时间是整数,因此您可以调整dynamic programming approach for Knapsack

我建议尝试使用基于子问题f(t)的动态编程来解决这个问题,这是调度截止时间小于或等于t的所有任务的最小惩罚。

答案 1 :(得分:1)

我通过动态编程解决了它。 f [i] i - 小时可获得的最高奖励。解决方案是 f [max(r)] ,其中 max(r)是截止日期中的最大值。

在我的解决方案中,您还需要一个列表 X [i] ,其中X [i]代表您应该通过 i -th执行的最佳任务列表小时获得最大奖项。

这里的伪代码:

LIST x0...n = empty;  // x0, x1....xn are all different lists
f[0] = 0;
for i=1 to max(r) do
    max = f[i-1];
    x[i] = x[i-1];
    for j=1 to n do
        if t[j] <= i and r[j] >= i and j.isNotElementOf(x[f[i-t[j]]]) then
            reward = p[j] + f[i-t[j]];
            if reward > max then
                max = reward;;
                x[i] = x[i-t[j]];
                x[i].add(j);
    f[i] = max;
return f[max(r)];