贪心_两类活动安排问题

贪心算法

活动安排问题算是典型的贪心问题了, 而且也和生活紧密联系.

活动安排问题有两种非常相近的形式, 贪的方法也很相似.
因为之前做过期中一个问题, 做第二种问题时转不过思维来, 卡在那不知道怎么做.

手动模拟的时候, 突然明白过来, 靠, 原来是这样!!!

先分析第一题:

有若干个活动,第i个开始时间和结束时间是[Si,fi),只有一个教室, 请问最多可以安排多少个活动?

思路:

把它的fi排序, 然后从小到大遍历可能的活动. 结果就是最大的活动数.

这题比较简单, 不提供代码

分析第二题:

有若干个活动,第i个开始时间和结束时间是(Si,fi),同一个教室安排的活动之间不能交叠,求要安排所有活动,最少需要几个教室?

这道题思考了很久, 就是不知道怎么贪心最好.
试着用第一题的思路, 每次把剩余的活动加入到教室, 直到没有活动为止, 看用了多少个教室.

思路是:

把每一个活动时间接到结束时间最近的时间序列(教室数), 不能接就另开新行.
具体理解还要做一做图模拟模拟.

代码

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

struct th {int s, e; } arr[10005];

bool cmp(th x, th y) {return x.s < y.s;}

int main()
{
    int n;
    cin >> n;
    priority_queue<int,vector<int>, greater<int> > myqueue;
    for(int i = 0; i < n; ++i) {
        cin >> arr[i].s >> arr[i].e;
    }
    sort(arr, arr+n, cmp);
    int ans = 1;
    myqueue.push(arr[0].e);
    for(int i = 1; i < n; ++i) {
        if(arr[i].s < myqueue.top()) {
            ans++;
            myqueue.push(arr[i].e);
        } else {
            myqueue.pop();
            myqueue.push(arr[i].e);
        }
    }
    cout << ans;
}
/*
4
1 3
2 5
3 4
6 8
*/

这个代码中使用了优先队列, 默认的优先队列是大的优先级最大, 此例可以调整.

priority_queue< int,vector, greater > myqueue; //从小到大
priority_queue< int,vector, less > myqueue; //从大到小(默认)

int 是可换的。

至于这道题问什么这么贪心,改变顺序分析一下,会发现不会有更优解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值