活动安排问题(贪心)

题目描述

活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合,是可以用贪心算法有效求解的很好例子。
该问题要求高效地安排一系列争用某一公共资源的活动。 贪心算法提供了一个简单、漂亮的方法使得尽可能多的活动能兼容地使用公共资源。
设有n个活动的集合E={1,2,…,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。
每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si<fi。如果选择了活动i,则它在半开时间区间[si ,fi
)内占用资源。若区间[si ,fi )与区间[sj,fj )不相交,则称活动i与活动j是相容的。当 si ≥ fj 或 sj ≥ fi
时,活动i与活动j相容。 活动安排问题就是在所给的活动集合中选出最大的相容活动子集合。
在这里插入图片描述

题解思路

数据结构

struct action{
	int s;			//起始时间
	int f;			//结束时间
	int index;		//活动的编号
};

活动的集合E记为数组:

action a[1000];
贪心策略:按活动的结束时间升序排序

排序比较因子:

bool cmp(const action &a, const action &b)
{
	if (a.f<=b.f) return true;
	return false;
}

使用标准模板库函数排序(下标0未用):

sort(a, a+n+1, cmp);

//形参数组b用来记录被选中的活动

void GreedySelector(int n, action a[], bool b[])
{
  b[1] = true;     //第1个活动是必选的
  //记录最近一次加入到集合b中的活动
  int preEnd = 1;
  for(int i=2; i<=n; i++)
    if (a[i].s>=a[preEnd].f)
    {
      b[i] = true;
      preEnd = i;
    }
}

在这里插入图片描述
在这里插入图片描述

完整代码

#include <iostream>
#include<bits/stdc++.h>
#define N 1001
#define INF 0x3f3f3f3f
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define rep(i,a,n) for(int i=a;i<=n;i++)
typedef long long ll;
using namespace std;
struct action
{
    int s;//起始时间
    int f;//结束时间
    int index;//活动的编号
} a[1000];
bool cmp(const action&a,const action &b)
{
    if(a.f<=b.f)return true;//升序
    return false;
}
int main()
{
    int n;
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>a[i].s;
        cin>>a[i].f;
    }
    sort(a, a+n+1, cmp);
    bool b[1000];
    for(int i=1;i<=n;i++)
    {
       b[i]=false;
    }
    b[1] = true;
    int preEnd = 1;
    for(int i=2;i<=n;i++)
    {
        if(a[i].s>=a[preEnd].f)
        {
            b[i]=true;
            preEnd=i;
        }
    }
    for(int i=1;i<=n;i++)
    {
        cout<<b[i]<<endl;
    }
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值