题目:ACwing 1349. 修理牛棚
题目来源:https://www.acwing.com/problem/content/1351/
描述:
在一个下着暴风雨的夜晚,大风掀翻了农夫约翰的牛棚的屋顶和大门。
牛棚一个个的并排排成一排,奶牛就住在牛棚中过夜。
由于一些奶牛正在外面度假,牛棚并没有住满,有的牛棚住着牛,有的牛棚空着。
所有的棚子的宽度都相同。
现在,约翰需要订购一批木板用来挡在牛棚的门口。
木材供应商将为他提供任意长度的木板,但是能够提供的木板数量非常有限。
约翰希望他购买的木板的总长度尽可能的小。
现在,给定可以购买的最大木板数量 M,牛棚的总数 S,牛的总数 C,以及 C 个住着牛的牛棚编号。
请你计算确保购买的木板的总长度尽可能小的情况下,为了使所有住着牛的牛棚都用木板挡住门,最少要将多少牛棚的门用木板挡住。
输入格式
第一行包含三个整数 M,S,C。
接下来 C 行,每行包含一个整数,表示一个住着牛的牛棚的编号。
输出格式
输出一个整数,表示被木板挡住门的牛棚的数量。
数据范围
$1≤M≤50,$
$1≤S≤200,$
$1≤C≤S,$
牛棚编号依次为 1∼S。
输入样例:
1 | 4 50 18 |
输出样例:
1 | 25 |
样例解释
一种可行的方案是,用一个木板将 3∼8 号牛棚的门挡住,一个木板将 14∼21 号牛棚的门挡住,一个木板将 25∼31 号牛棚的门挡住,一个木板将 40∼43 号牛棚的门挡住,这样一共遮挡了 25 个牛棚的门。
算法1:$O(nlog n)$
题目大意:
给定m块木板长度随意,有一排牛棚,有些牛棚有牛有些没有。问在木板数量一定的时候,最少需要覆盖多少牛棚才能把有牛的牛棚给覆盖完。
思路:
这时候可以考虑一个补集的思想,首先用一整块木板使所有牛棚都覆盖掉 长度 = 终点 - 起点 + 1
, 然后再对空牛棚的间隔长度
进行从大到小排序。
有m块木板,最多可以去掉 m - 1
个空牛棚间隙。去掉 m - 1
个间隙后一定是在m块木板下总木板长度最短。
证明:
原问题的选法,对m块木板的长度选法一定一一对应选m - 1个区间。m - 1个区间的长度 + m 块木板的长度 = 总牛棚的数量
。
总牛棚的数量不变,要想m块木板的长度最小,只用 m - 1个区间的长度
最大即可。对没有牛棚的区间长度进行从大到小排序,依次选择前 m - 1个区间。
时间复杂度分析:
只用到了排序,所以时间复杂度$O(nlog n)$
1 |
|