贪心_HDOJ2037/NYOJ14最大区间调度问题

原题地址http://acm.hdu.edu.cn/showproblem.php?pid=2037

题目概述:

Input

输入数据包含多个测试实例,每个测试实例的第一行只有一个整数n(n<=100),表示你喜欢看的节目的总数,然后是n行数据,每行包括两个数据Ti_s,Ti_e (1<=i<=n),分别表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。n=0表示输入结束,不做处理。
Output
对于每个测试实例,输出能完整看到的电视节目的个数,每个测试实例的输出占一行。
 Sample Input
12
1 3
3 4
0 7
3 8
15 19
15 20
10 15
8 18
6 12
5 10
4 14
2 9
0
Sample Output
5
题目分析:
经典时间序列问题,贪心算法,只考虑当前,不考虑全局,每次只考虑局部最优解,按右端点排序,依次处理。
/*给出节目开始和结束时间要求输出能看完的节目的数量*/
#include<bits/stdc++.h>
using namespace std;
struct TIME
{
    int time_begin;
    int time_end;
};
bool f(const TIME &a,const TIME &b)
{
    return a.time_end < b.time_end;//按右端点排序
}
int main(void)
{
    int n;
    while(cin >> n && n)
    {
        vector<TIME> my_vec;
        while(n--) //输入和存储数据
        {
            TIME t;
            cin >> t.time_begin >> t.time_end;
            my_vec.push_back(t);
        }
        sort(my_vec.begin(),my_vec.end(),f);
        vector<TIME>::iterator begin = my_vec.begin(),end = my_vec.end();
        int sum = 1;//记录最多的空间数
        TIME tmp = *begin;
        ++begin;
        //begin 从第二个开始,因为上去就先把第一个选了 sum也从1开始
        while(begin != end)
        {
            //每次选取区间时候和前一个比较看是否覆盖
            //.操作符比*操作符优先级高 得加小括号
            if( (*begin).time_begin >= tmp.time_end )
            {
                sum++;
                tmp = *begin; //更新tmp tmp表示最新被选上的区间
            }
            ++begin;//往下走
        }
        cout << sum << endl;
    }

    return 0;
}

 NYOJ14会场安排问题 链接http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=14

题目大意,知道活动开始和结束时间,要求出最多进行的活动

 

/*知道活动开始结束的时间,要求安排最多的活动,区间问题
 * 如果上一个活动是t结束,下一个活动最早应该t+1开始*/
#include<bits/stdc++.h>
using namespace std;
struct S
{
    int L;
    int R;
};
bool f(const S &a,const S &b)
{
    return a.R < b.R;
}
int main(void)
{
    int N;
    cin >> N;
    while(N--)
    {
        int n;
        vector<S> v;
        cin >> n;
        while(n--)
        {
            S t;
            cin >> t.L >> t.R;
            v.push_back(t);
        }
        sort(v.begin(),v.end(),f);//按右端点排序
        int count = 1,end = v[0].R;
        for(int i = 1; i < v.size();++i)
        {
            if(v[i].L > end)
            {
                end = v[i].R;
                ++count;
            }
        }
        cout << count << endl;
    }

    return 0;
}

 最大区间调度问题

  数轴上有个区间,选出最多的区间,使得这些区间不互相重叠。 

算法:

 将所有区间按右端点坐标从小到大排序,顺序处理每个区间。如果它与当前已选的所有区间都没有重叠,则选择该区间,否则不选。

 

 

posted @ 2018-05-17 14:31  凉菜花生小酒  阅读(236)  评论(0)    收藏  举报