zoukankan      html  css  js  c++  java
  • - > 贪心基础入门讲解二——活动安排问题

    有若干个活动,第i个开始时间和结束时间是[Si,fi),只有一个教室,活动之间不能交叠,求最多安排多少个活动?

    分析: 我们就是想提高教室地利用率,尽可能多地安排活动。
    考虑容易想到的几种贪心策略:

    (1) 开始最早的活动优先,目标是想尽早结束活动,让出教室。
    然而, 这个显然不行,因为最早的活动可能很长,影响我们进行后面的活动。例如活动开始和结束时间分别为[0, 100), [1,2) ,[2, 3), [3, 4),[4,5],安排[0,100)的这个活动之后,其他活动无法安排,可是最优解是安排除它外的4个活动。

    (2) 短活动优先, 目标也是尽量空出教室。但是不难构造如下反例: [0,5) [5,10) [3, 7), 这里[3,7)最短,但如果我们安排了[3,7),其它两个无法安排了。但是最优解显然是安排其它两个,而放弃[3,7),可见这个贪心策略也是不行的。
     
    (3) 最少冲突的活动优先, 既然上面安排活动是想减少冲突,那么如果我们优先安排冲突最少的活动可以么?至少从(1)和(2)看来,这个策略是有效的。真是对的么? 尝试这个例子:

    [0,2) [2,4) [4,6) [6,8)
    [1,3) [1,3) [1,3) [3,5) [5,7) [5,7) [5,7)

     
    看一下[0,2) 和3个活动冲突——3个[1,3)

    [2,4)和4个活动冲突3个[1,3)和一个[3,5)
    [4,6)和也和4个活动冲突3个[5,7)和一个[3,5)
    [6,8)和3个活动冲突——3个[5,7)

    下面[1,3)和[5,7)每个都和5个活动冲突,
    而[3,5)只和两个活动冲突——[2,4)和[4,6)。

    那按照我们的策略应该先安排[3,5), 可是一旦选择了[3,5),我们最多只可能安排3个活动。
    但明显第一行的4个活动都可以安排下来,所以这种策略也是不对的。
    (4) 看似最不对的策略——结束时间越早的活动优先。这个策略是有效的,我们可以证明。假设最优解OPT中安排了m个活动,我们把这些活动也按照结束时间由小到大排序,显然是不冲突的。假设排好顺序后,这些活动是a(1) , a(2), a(3)….am

    假设按照我们的贪心策略,选出的活动自然是按照结束时间排好顺序的,并且也都是不冲突的,这些活动是b(1), b(2) …b(n)

    问题关键是,假设a(1) = b(1), a(2) = b(2)…. a(k) = b(k),但是a(k+1) != b(k+1),回答几个问题:
     
    (1)b(k+1)会在a(k+2), a(k+3), …. a(m)中出现么?
    不会。因为b(k+1)的结束时间是最早的,即f(b(k+1)) <= f(a(k+1)),而a(k+2), a(k+3), …. a(m)的开始时间和结束时间都在f(a(k+1))之后,所以b(k+1)不在其中。

    (2)b(k+1)和a(1), a(2), …. a(k) 冲突么?
    不冲突,因为a(1), a(2), …. a(k)就是b(1), b(2), …. b(k)

    (3)b(k+1)和a(k+2), a(k+3), …. a(m)冲突么?
    不冲突,因为f(b(k+1)) <= f(a(k+1)),而a(k+2), a(k+3), …. a(m)的开始时间都在f(a(k+1))之后,更在f(b(k+1))之后。

    因此我们可以把a(k+1) 换成b(k+1), 从而最优解和我们贪心得到的解多了一个相同的,经过一个一个替换,我们可以把最优解完全替换成我们贪心策略得到的解。 从而证明了这个贪心策略的最优性。
    输入

    第1行:1个数N,线段的数量(2 <= N <= 10000)
    第2 - N + 1行:每行2个数,线段的起点和终点(-10^9 <= S,E <= 10^9)
    输出
     
    输出最多可以选择的线段数量。
     
    输入示例

    3
    1 5
    2 3
    3 6

    输出示例

    2
     
    请选取你熟悉的语言,并在下面的代码框中完成你的程序,注意数据范围,最终结果会造成Int32溢出,这样会输出错误的答案。
    不同语言如何处理输入输出,请查看下面的语言说明。
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,ans,a[10010],b[10010],v[10010];
    void scanfcin()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i]>>b[i];
            if(a[i]>b[i])
            swap(a[i],b[i]);
        }
    }
    void paixu()
    {
        for(int i=1;i<n;i++)
            for(int j=i+1;j<=n;j++)
            {
                if(b[i]>b[j])
                {
                    swap(a[i],a[j]);
                    swap(b[i],b[j]);    
                }
            }
    }
    void jisuansuchu()
    {
        ans=n;
        for(int i=2;i<=n;i++)
        {
            if(a[i]<b[i-1])
            {
                ans--;
                b[i]=b[i-1];
            }
        }    
        cout<<ans;
    }
    int main()
    {
        scanfcin();
        paixu();
        jisuansuchu();
        return 0;
    }

     如果对你有所帮助,别忘了加好评哦;么么哒!!下次见!88

    细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。 雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。
  • 相关阅读:
    Lock wait timeout exceeded; try restarting transaction linux设置mysql innodb_lock_wait_timeout
    用NaviCat创建存储过程批量添加测试数据
    mysql存储过程语法及实例
    mysql中迅速插入百万条测试数据的方法
    mysql学习之通过文件创建数据库以及添加数据
    有用的网站集合
    VMware Workstation虚拟磁盘文件备份或移植
    CoreData修改了数据模型报错 The model used to open the store is incompatible with the one used to create the store
    iOS中自定义UITableViewCell的用法
    golang make()的第三个参数
  • 原文地址:https://www.cnblogs.com/cangT-Tlan/p/6219025.html
Copyright © 2011-2022 走看看