贪心算法——区间调度问题

题目描述

有N项工作,每项工作分别在Si时间开始,在Ti时间结束。对于每项工作,你都可以选择参与与否。如果选择了参与,那么自始至终都必须全程参与。此外,参与工作的时间段不能重叠(即使是开始的瞬间和结束的瞬间重叠也是不允许的)。

  目标是尽可能参与可能多的工作,那么最多能参与多少项工作?

样例输入

n = 5, s= {1,2,4,6,8}, t={3,5,7,9,10}

样例输出

3 (选取工作1、3、5)

思路分析

贪心算法之所以能用,是基于以“结束时间最早”为前提的。但是这是需要你分析和证明的,你要先想明白为什么 按结束时间最早排序才是正确的。

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

AC代码

#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];
        itv[i].second = S[i];
    }
    /*
    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");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想要offer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值