Weighted Interval Scheduling

带权重的区间调度问题

  • Problem description
    • Analysis
  • Code
  • Ref

Problem description

  给定若干个工作的开始时间、结束时间和权重(可以理解成重要程度),求出能完成的最大的工作权重(尽可能地完成更重要的工作),当然必须满足各个工作相容。如以下三个工作:

开始时间 结束时间 权重
工作1 0 3 4
工作2 5 6 5
工作3 2 8 10

  由不带权重的区间调度方法,依次结束时间最早且相容的工作,这里就选出{1, 2},能实现的最大权重是4+5=9。而显而易见,选择{3}权重可达到10,因此最早结束时间的贪心策略在带权重的区间调度问题里已不适用

Analysis

Weighted Interval Scheduling_第1张图片

各工作开始与结束时间

  给出上图所示8个工作的开始结束时间,按结束时间升序排序(区间调度问题一般都会先按结束时间升序排序)。 数据说明如下:

  • 工作数目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个工作考虑结束后所能达到的最大权值
  • frt[n]frt[i]表示序列中前一与之相容的最大工作编号。如frt[8]=5,frt[6]=2
    Weighted Interval Scheduling_第2张图片
    按结束时间排序

  考虑状态转移方程。对于每个工作i,比较dp[i-1]和v[i]+dp[frt[i]],取较大者为dp[i]

Weighted Interval Scheduling_第3张图片

状态转移方程

Code

#include 
#include 
#include 

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){ //定义按结束时间升序排序的排序规则
    return a.e<b.e;
}
/*bool cmps(JOB a, JOB b){ //定义按开始时间升序排序的排序规则
    return a.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;
    //按结束时间升序排序,并为元素编号
    sort(job, job+n, cmpe);
    for(int i=1; i<=n; i++) job[i].index=i;
    //求frt[]数组
    //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;
}

Ref

1、带权重的区间调度问题——动态规划.
2、Weighted Interval Scheduling VS Interval Scheduling.
3、Weighted Interval Scheduling.

你可能感兴趣的:(算法分析,贪心算法)