帶權(quán)重的區(qū)間調(diào)度問題——動態(tài)規(guī)劃

問題闡述

??給定若干個工作的開始時間、結(jié)束時間和權(quán)重(可以理解成重要程度),求出能完成的最大的工作權(quán)重(盡可能地完成更重要的工作),當然必須滿足各個工作相容。如以下三個工作:
????????????? 開始時間 ???結(jié)束時間 ???權(quán)重
工作1???????????0???????????????3??????????????4
工作2???????????5???????????????6??????????????5
工作3???????????2???????????????8?????????????10
??由不帶權(quán)重的區(qū)間調(diào)度方法,依次結(jié)束時間最早且相容的工作,這里就選出{1, 2},能實現(xiàn)的最大權(quán)重是4+5=9。而顯而易見,選擇{3}權(quán)重可達到10,因此最早結(jié)束時間的貪心策略在帶權(quán)重的區(qū)間調(diào)度問題里已不適用

分析

各工作開始與結(jié)束時間

??給出上圖所示8個工作的開始結(jié)束時間,按結(jié)束時間升序排序(區(qū)間調(diào)度問題一般都會先按結(jié)束時間升序排序)。 數(shù)據(jù)說明如下:

  • 工作數(shù)目n
  • 聲明結(jié)構(gòu)體數(shù)組存儲工作的開始、結(jié)束時間和權(quán)值
struct JOB{
    int s, e, v;
    JOB(int s=0, int e=0, int v=0):s(s), e(e), v(v){}
}job[maxn];
  • dp[n],dp[i]表示對前1個工作考慮結(jié)束后所能達到的最大權(quán)值
  • frt[n],frt[i]表示序列中前一與之相容的最大工作編號。如frt[8]=5,frt[6]=2
按結(jié)束時間排序

??考慮狀態(tài)轉(zhuǎn)移方程。對于每個工作i,比較dp[i-1]和v[i]+dp[frt[i]],取較大者為dp[i]

狀態(tài)轉(zhuǎn)移方程

代碼實現(xiàn)

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;
const int maxn = 205;
struct JOB{
    int s, e, v, index;
    JOB(int s=0, int e=0, int v=0, int index=0):s(s), e(e), v(v), index(index){}
}job[maxn];
int frt[maxn], dp[maxn];

bool cmpe(JOB a, JOB b){ //定義按結(jié)束時間升序排序的排序規(guī)則
    return a.e<b.e;
}
/*bool cmps(JOB a, JOB b){ //定義按開始時間升序排序的排序規(guī)則
    return a.s<b.s;
}*/

int main()
{
    int n; cin >> n;
    //JOB a=(1,2,3);
    memset(frt, 0, sizeof(frt));
    memset(dp, 0, sizeof(dp));
    for(int i=1;i<=n;i++) cin >> job[i].s >> job[i].e >> job[i].v;
    //按結(jié)束時間升序排序,并為元素編號
    sort(job, job+n, cmpe);
    for(int i=1; i<=n; i++) job[i].index=i;
    //求frt[]數(shù)組
    //sort(job, job+n, cmps); //按開始時間升序排列
    for(int i=n;i>0;i--){
        for(int j=n-1;j>0;j--){
            if(job[j].e<=job[i].s) {frt[i]=job[j].index; break;}
        }
    }
    //sort(job, job+n, cmpe);
    for(int i=1;i<=n;i++){
        dp[i] = max(dp[i-1], dp[frt[i]]+job[i].v);
    }
    cout << dp[n];
    return 0;
}

老師的ppt里有一句話,“按開始時間排序后,計算frt數(shù)組的復雜度為O(n)”,但我沒想出來怎么個O(n)法,上面代碼還是用的簡單的遍歷,希望看到這里的朋友能不吝賜教>_<

Tips

  • 自定義sort函數(shù)的排序規(guī)則
  • 在O(nlogn)時間內(nèi)計算frt數(shù)組的技巧(我不知道)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容