区间调度问题_单线程(最多、最大区间)

1、最多区间调度

转自:https://www.cnblogs.com/yjlblog/p/7506887.html 本文由 YJLAugus 创作(这个大佬的博客还挺萌的)

问题描述:

有n项工作,每项工作分别在si开始,ti结束。对每项工作,你都可以选择参加或不参加,但选择了参加某项工作就必须至始至终参加全程参与,即参与工作的时间段不能有重叠(即使开始的时间和结束的时间重叠都不行)。求最多参加几项工作。

样例:

输入

n=5

s={1,2,4,6,8}

T={3,5,7,9,10}

输出

3(选择工作1, 3, 5)

解决方法:优先完成结束最早的工作

  • 因为结束时间最早,所以取相同数量的工作肯定它最早结束或至少不晚。
  • 如果后面还有工作,那么加入到结束最早算法的空间更大。 因此就不会存在比它更多工作的可能。

而以下几种方法都不行:

(1)、每次选取开始时间最早的;不行!

(2)、每次选取用时最短的;不行!

(3)、在可选工作中,每次选取与最小可选工作有重叠的部分;不行!

#include <iostream>
#include <algorithm>
using namespace std;
/*
1:每次选取结束时间最早的任务
2:选取T数字最小的时间段
*/
const int MAX_N = 100000;//方便更改更大的值
int N = 5, S[MAX_N] = { 1,2,4,6,8 }, T[MAX_N] = { 3,5,7,9,10 };//输入,S开始时间,T结束时间
pair<int, int> itv[MAX_N];//用于对工作排序的pair数组

void solve() 
{
    for (int i = 0; i < N; i++)//先把数据存入
    {
        itv[i].first = T[i];//first存结束时间 
        itv[i].second = S[i];//second存开始时间 
    }
    /*
    sort:首先根据first进行排序,first数据相同根据second排序【重点(注意sort执行的过程)】
    按照由小及大进行排序,即按照结束时间最小进行排序,结束时间相同按照开始时间最小进行排序。
    */
    sort(itv, itv + N);
    int ans = 0, t = 0;//t是最后所选工作结束的时间
    /*
    结束时间小于下一个最先结束的可执行时间,即开始时间 
    */
    for (int i = 0; i < N; i++) 
    {
        if (t < itv[i].second)//判断区间是否重叠  
        {
            ans++;
            t = itv[i].first;
        }
    }
    cout << ans << endl;
}
int main() {
    solve();
    system("pause");
}

2、最大区间调度

该问题和上面最多区间调度问题的区别是不考虑区间个数,而是将区间的长度和作为一个指标,然后求长度和的最大值。我们将该问题命名为最大区间调度问题。

现在有n个工作要完成,每项工作分别在 时间开始,在 时间结束。对于每项工作,你都可以选择参与与否。如果选择了参与,那么自始至终都必须全程参与。此外,参与工作的时间段不能重叠(闭区间)。求你参与的所有工作最大需要耗费多少时间。

const int MAX_N=100000;  
//输入  
int N,S[MAX_N],T[MAX_N];  
  
//用于对工作排序的pair数组  
pair<int,int> itv[MAX_N];  
  
void solve()  
{  
    //对pair进行的是字典序比较,为了让结束时间早的工作排在前面,把T存入first,//把S存入second  
    for(int i=0;i<N;i++)  
    {  
        itv[i].first=T[i];  
        itv[i].second=S[i];  
    }  
  
    sort(itv,itv+N);  
  
    dp[0] = itv[0].first-itv[0].second;  
    for (int i = 1; i < N; i++)  
    {  
        int max;  
  
        //select the ith interval  
        int nonOverlap = lower_bound(itv, itv[i].second)-1;  
        if (nonOverlap >= 0)  
            max = dp[nonOverlap] + (itv[i].first-itv[i].second);  
        else  
            max = itv[i].first-itv[i].second;  
  
        //do not select the ith interval  
        dp[i] = max>dp[i-1]?max:dp[i-1];  
    }  
    printf(“%d\n”,dp[N-1]);  
} 

还有更多问题

转自https://blog.csdn.net/kiritow/article/details/52208488

猜你喜欢

转载自blog.csdn.net/aaakkk_1996/article/details/81611928
今日推荐