Weighted Interval Scheduling

带权重的区间调度问题

Problem description

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

开始时间结束时间权重
工作1034
工作2565
工作32810

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

Analysis

各个工作开始与结束时间

各工作开始与结束时间

  给出上图所示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
    按结束时间排序
    按结束时间排序

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

状态转移方程

状态转移方程

Code

#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){ //定义按结束时间升序排序的排序规则
    return a.e<b.e;
}
/*bool cmps(JOB a, JOB b){ //定义按开始时间升序排序的排序规则
    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;
    //按结束时间升序排序,并为元素编号
    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.

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值