algorithm - 使用动态规划实现事件选择问题

标签 algorithm dynamic-programming recurrence greedy

如何使用动态规划实现事件选择问题(CLRS 练习 16.1-1)。我已经使用 Greedy Method 实现了它,它以线性时间运行(假设数组已经按完成时间排序)。

我知道它构成了最优子结构。

$S_{ij}$ 事件集在事件 $a_i$ 完成后开始,并且 在事件 $a_j$ 开始之前完成。如果我们用 $c[i j]$ 表示集合 $S_{ij}$ 的最优解的大小,那么我们将得到递归

$c[i j]  = c[i k] + c[k j] + 1$

最佳答案

我们可以使用动态规划来解决它,方法是保持一个状态,该状态包含有关事件的当前索引的详细信息以及到目前为止我们已经采取的事件的当前完成时间,在事件的每个索引处我们可以使 2决定是否选择一项事件,最后我们需要选择和递归的最大值。 我已经在 C++ 中实现了递归 dp 解决方案:

#include<bits/stdc++.h>

using namespace std;

int n;
int st[1000], en[1000];
int dp[1000][1000];

int solve(int index, int currentFinishTime){
    if(index == n) return 0;
    int v1 = 0, v2 = 0;
    if(dp[index][currentFinishTime] != -1) return dp[index][currentFinishTime];

    //do not choose the current activity
    v1 = solve(index+1, currentFinishTime);

    //try to choose the current activity
    if(st[index] >= currentFinishTime){
        v2 = solve(index+1, en[index]) + 1;
    }
    return dp[index][currentFinishTime] = max(v1, v2);
}

int main(){
    cin >> n;
    for(int i = 0;i < n;i++) cin >> st[i] >> en[i];
    memset(dp, -1, sizeof dp);

    cout << solve(0, 0) << endl;
return 0;
}

http://ideone.com/m0mxx2

在此代码中,dp[index][finish time] 是用于存储结果的 dp 表。

关于algorithm - 使用动态规划实现事件选择问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33594525/

相关文章:

Python菱形方 block 算法实现

algorithm - 客户端服务请求的隐式 "Authentication"

algorithm - 在列表中查找元素集,元素只能使用一次 - 如何处理算法

math - 计算机科学数学中的递归关系 T(n) = 6T(n/6) + 2n + 3 对于 n 的 6 次方 T(1) = 1?

algorithm - 动态规划练习的递归关系

java - 一次仅使用 2 个成员的平均值查找数组的平均值

algorithm - 二维矩阵中的最佳方形覆盖(最小化覆盖成本)

dynamic-programming - leetcode中AC是什么意思,是DP等算法技术吗?

c++ - 用 2x1 block 平铺 2xM 阵列以最大化差异 - INOI 2008,P2

c++ - 算法的递归关系