Algorithm:贪心策略之区间调度问题

Describe:
有n项工作,每项工作分别再si时间开始,在ti时间结束;对于每项工作,你都可以参与与否,如果选择参与,那么自始自终都必须全程参与;此外参加工作的时间段不能重复(即使是开始的瞬间和结束的瞬间的重叠也不允许);
你的目标是参与尽可能多的工作,那么最多能参与多少项工作呢?
1<=n<=100000
1<=si<=ti<=10^9
输入:
第一行:n
第二行:n个整数空格隔开,代表n个工作的开始时间
第三行:n个整数空格隔开,代表n个工作的结束时间

样例输入:
5
1 2 4 6 8
3 5 7 9 10
样例输出:
3

Thinking:
在这里插入图片描述
最终我们需要将一个个事件按结束时间排序,如何让它们排序并且保证每个事件的开始、结束时间是对应的呢?
这里是将 si 和 ti 作为一个类的成员变量,然后构建对象数组;

#include <iostream>
#include <algorithm>
using namespace std;

class Thing //建立事件类,里面存放事件的起始时间s,终止时间e
{
public:
    int s;
    int e;
    Thing(int ss = 0, int ee = 0) //构造函数
    {
        s = ss;
        e = ee;
    }
};

bool compare(Thing a, Thing b)//自定义sort函数的第三个参数--排序函数,因为sort并不能按原有排序函数对类生成的对象进行排序
{
    return a.e < b.e; //意思就是 a.e比b.e小 ,a要在b前面
}

int fun(int n, int si[], int ti[])
{
    int count = 1;//计数,此处代表第一个事件完成

    Thing th[n];
    for (int i = 0; i < n; i++) //对类的对象赋值
    {
        th[i].s = si[i];
        th[i].e = ti[i];
    }
    sort(th, &th[n-1], compare);//sort排序(要排序的数组的起始地址,最后一个要排序的地址,排序函数)

    int last = th[0].e;
    for (int i = 1; i < n; i++)//依次找跟在上一个事件后的事件(下一件事的开始时间大于上一件事的结束时间)
    {
        if (th[i].s > last)
        {
            count++;
            last = th[i].e;
        }
    }
    return count;
}
int main()
{
    int n = 5;
    int si[] = {1, 2, 4, 6, 8};
    int ti[] = {4, 3, 7, 9, 10};
    cout << fun(n, si, ti);//输出结果为3
    return 0;
}

排完序后是这样的(这里没有用样例,因为它本来就是有序的)
在这里插入图片描述
所以以后遇到区间调度问题,应想到按结束时间排序即可得解!
如有错误,感谢指正!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用C++实现贪心算法解决区间调度问题的示例代码: ```cpp #include <iostream> #include <vector> #include <algorithm> // 区间结构体 struct Interval { int start; int end; }; // 比较函数,根据结束时间排序 bool compareIntervals(Interval a, Interval b) { return a.end < b.end; } // 贪心算法解决区间调度问题 int intervalScheduling(std::vector<Interval>& intervals) { // 按照结束时间排序 std::sort(intervals.begin(), intervals.end(), compareIntervals); int count = 1; // 最少需要一个区间 int endTime = intervals[0].end; // 遍历区间,选择结束时间最早的不冲突区间 for (int i = 1; i < intervals.size(); i++) { if (intervals[i].start >= endTime) { count++; endTime = intervals[i].end; } } return count; } int main() { std::vector<Interval> intervals = {{1, 3}, {2, 4}, {3, 6}, {5, 7}, {6, 8}}; int result = intervalScheduling(intervals); std::cout << "最多可安排的任务数量: " << result << std::endl; return 0; } ``` 在这个示例中,我们定义了一个`Interval`结构体来表示区间,并实现了一个比较函数`compareIntervals`,用于根据结束时间对区间进行排序。`intervalScheduling`函数使用贪心算法解决区间调度问题,首先对区间按照结束时间进行排序,然后从第一个区间开始遍历,选择结束时间最早的不冲突区间,并计数。最后输出最多可安排的任务数量。 在主函数中,我们创建了一个包含几个区间的示例输入,然后调用`intervalScheduling`函数计算结果,并输出最多可安排的任务数量。 注意:这只是一个简单的示例,实际问题可能需要根据具体情况进行更复杂的处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值