使用动态编程实现活动选择问题

时间:2015-11-08 13:33:12

标签: algorithm dynamic-programming recurrence greedy

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

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

$S_{ij}$在活动$a_i$完成后开始的一系列活动 在活动$a_j$开始之前完成。如果我们表示集$S_{ij}$ by $c[i j]$的最优解的大小,那么我们就会有重复

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

1 个答案:

答案 0 :(得分:2)

我们可以使用动态编程来解决它,方法是保存一个状态,其中包含活动的当前索引的详细信息以及我们已经采取的活动的当前完成时间,我们可以在每个活动的索引处进行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表。