dp - 活動選擇問題
阿新 • • 發佈:2018-03-12
需要 我們 思考 方法 end problem ctp 時間復雜度 ble
活動選擇問題是一類任務調度的問題,目標是選出一個最大的互相兼容的活動集合。例如:學校教室的安排問題,幾個班級需要在同一天使用同一間教室,但其中一些班級的使用時間產生沖突,一些班級的時間是兼容的,我們需要找出最大的相互兼容的這樣一個集合。實際上,運用‘貪心’的思想,可以準確又效率的找出這樣一個集合,但為了練習一下動態規劃,這篇使用了dp的做法。
最優子結構以及遞歸公式書中給出了詳細的分析過程,但課後練習題要求使用動態規劃用代碼實現算法,於是我就給出我的代碼:
#include "stdafx.h" #include <iostream> #include <minmax.h> #include <vector> class DP { public: int ActivitySelectProblem(std::vector<int> & s, std::vector<int> & f) { std::vector<std::vector<int> > dp(s.size() - 1, std::vector<int>(s.size() - 1)); int count = 0; for (int l = 1; l < s.size(); l++) for (int i = 0; i < s.size() - l; i++) { int j = i + l - 1; dp[i][j] = 0; for (int k = i; k < j; k++) { if (f[i] <= s[k + 1]) dp[i][j] = max(dp[i][j], dp[i][k] + dp[k][j] + 1); count = max(count, dp[i][j] - 1); } } return count; } }; int main() { std::vector<int> s{ 1,3,0,5,3,5,6,8,8,2,12,17 }; std::vector<int> f{ 4,5,6,7,9,9,10,11,12,14,16,21 }; std::cout << DP().ActivitySelectProblem(s, f) << std::endl; getchar(); return 0; }
有遞歸公式,那麽算法的實現是很簡單的。為了簡單,所以我使用返回集合的長度的方法,但實際上這是非常不顯然的,看不出是哪些班級相互兼容,但我也沒想到好辦法實現保存合格的班級的下標,然後返回集合。我再思考思考。。。時間復雜度O(n^3)。
dp - 活動選擇問題