[ 数据结构 ] 集合覆盖问题(贪心算法)
创始人
2024-05-09 14:04:27
0

0 集合覆盖问题

  1. 假设存在如下表的需要付费的广播台,以及广播台信号可以覆盖的地区。 如何选择最少的广播台,让所有的地区都可以接收到信号
广播台覆盖地区
K1北京,上海,天津
K2广州,北京,深圳
K3成都,上海,杭州
K4上海,天津
K5杭州,大连
  1. 思路分析①:穷举法,列出每个可能的广播台的集合,假设总的有 n 个广播台,则广播台的组合总共有2ⁿ -1 个,假设每秒可以计算 10 个子集, 如图:

image-20230109192838218.png

  1. 思路分析②:贪心算法,见下一章

1 贪心算法

  1. 目标:选择策略上,尽量选择最少的电台,并覆盖全部地区
  2. 首先:集合allAreas收录全部的8个地区,遍历所有电台并最终选择能覆盖最多地区的电台k(贪心)
  3. 删除allAreas中k所能覆盖的电台
  4. 在剩余的4个电台中重复第2步和第3步的操作
  5. 直到allAreas的大小为0,表示选择的电台已经覆盖全地区
  6. 即得到所选的电台集合

说明:整个过程中,其实重难点在第2步中如何选择能覆盖最多地区的电台,并不是选择最大的电台,而是k电台与allAreas的交集如果最大,说明k就是本轮我们选择的结果,allAreas其实应该理解为目前未被电台覆盖的地区

举例:当K1电台已经被选择后,在第二轮的选择情况如下(结果选K2电台):

广播台本轮电台覆盖地区数(交集)覆盖地区
K10北京,上海,天津
K22广州,北京,深圳
K32成都,上海,杭州
K40上海,天津
K52杭州,大连

ps:该算法的解并不一定是最优解,只是相对接近最优,因为当多个电台都能覆盖3个地区时,我们选择了第一个,这考虑的过于简单,比如第一个电台如果包月太贵那么是否应该考虑选第2个呢

2 代码实现

//贪心算法
public class GreedyAlgorithm {public static void main(String[] args) {//创建广播电台,放入到 MapHashMap> broadcasts = new HashMap>();//将各个电台放入到 broadcastsHashSet hashSet1 = new HashSet();hashSet1.add("北京");hashSet1.add("上海");hashSet1.add("天津");HashSet hashSet2 = new HashSet();hashSet2.add("广州");hashSet2.add("北京");hashSet2.add("深圳");HashSet hashSet3 = new HashSet();hashSet3.add("成都");hashSet3.add("上海");hashSet3.add("杭州");HashSet hashSet4 = new HashSet();hashSet4.add("上海");hashSet4.add("天津");HashSet hashSet5 = new HashSet();hashSet5.add("杭州");hashSet5.add("大连");//加入到 mapbroadcasts.put("K1", hashSet1);broadcasts.put("K2", hashSet2);broadcasts.put("K3", hashSet3);broadcasts.put("K4", hashSet4);broadcasts.put("K5", hashSet5);//allAreas 存放所有的地区HashSet allAreas = new HashSet();allAreas.add("北京");allAreas.add("上海");allAreas.add("天津");allAreas.add("广州");allAreas.add("深圳");allAreas.add("成都");allAreas.add("杭州");allAreas.add("大连");//选择结果List selects = new ArrayList();//存放最大结果集(即本轮选择的电台和其新覆盖的地区)String bigKey = "";HashSet bigSet =null;//存放遍历的结果与全地区的交集(即能覆盖的新地区)HashSet tempSet =null;//只要全地区还有元素,说明仍有地区未覆盖while (allAreas.size() > 0) {//遍历广播电台的同时,获取与全地区的交集,贪心:暂存本轮交集最大的电台for (String key : broadcasts.keySet()) {tempSet = broadcasts.get(key);tempSet.retainAll(allAreas);if (bigSet==null||broadcasts.get(key).size() > bigSet.size()) {bigSet= tempSet;bigKey = key;}}//收集本轮的电台选择结果并删除全地区中该电台覆盖的地区selects.add(bigKey);allAreas.removeAll(bigSet);}System.out.println(selects);}
}

相关内容

热门资讯

安卓系统的手机优缺点,全面解析... 你有没有发现,现在市面上手机种类繁多,让人挑花了眼?其中,安卓系统的手机可是占据了半壁江山呢!今天,...
平板有没有安卓系统,安卓系统引... 你有没有想过,平板电脑到底有没有安卓系统呢?这个问题听起来可能有点奇怪,但确实很多人在选购平板时都会...
安卓手机双系统好用不,安卓手机... 你有没有想过,你的安卓手机是不是也能像多面手一样,既能驾驭工作,又能享受娱乐呢?没错,说的就是那个神...
安卓系统怎么登录国际服,一键操... 你有没有想过,为什么有时候你的安卓手机上会出现那些国际服的游戏呢?是不是好奇怎么登录这些神秘的国外服...
安卓系统的时间天气没了,天气功... 最近你的安卓手机是不是也遇到了一个让人头疼的小问题?那就是——时间天气不见了!没错,就是那个曾经陪伴...
安卓好用的拍照系统,捕捉美好瞬... 你有没有发现,现在手机拍照功能越来越强大了?尤其是安卓手机,拍照系统简直让人爱不释手!今天,就让我带...
软件如何兼容安卓8系统,助您软... 你有没有发现,随着科技的飞速发展,手机软件更新换代的速度也是越来越快呢!这不,安卓8系统已经悄然来临...
安卓通用版系统下载,畅享智能生... 你有没有发现,最近手机界又掀起了一股热潮?没错,就是安卓通用版系统下载!这可是个让无数安卓用户兴奋不...
安卓无线点餐系统ph,PH技术... 你有没有想过,点餐也能变得如此轻松愉快?没错,就是那个我们每天都要面对的吃饭问题,现在有了安卓无线点...
安卓门禁系统怎么样,便捷通行新... 你有没有想过,每天回家时,只需轻轻一刷,门就自动打开了?这就是安卓门禁系统的魅力所在!今天,就让我带...
在电脑上模拟安卓系统,探索虚拟... 你有没有想过,在电脑上也能体验安卓系统的乐趣呢?没错,就是那种随时随地都能玩手机的感觉,现在也能在电...
飞机送餐安卓系统,空中美食新体... 你有没有想过,飞机上的美食是如何送到你手中的?是不是觉得这背后有着神秘的力量?其实,这一切都离不开高...
findx耍原生安卓系统,深度... 亲爱的读者们,你是否厌倦了那些花里胡哨的定制系统,渴望回到那个纯净的安卓世界?今天,我要带你一起探索...
一加系统属于安卓系统吗,引领智... 你有没有想过,手机里的那个神奇的“一加系统”到底是不是安卓系统的一员呢?这可是个让人好奇不已的问题哦...
小米2刷安卓系统吗,探索安卓系... 亲爱的读者,你是否曾经对小米2这款手机刷安卓系统的事情感到好奇呢?今天,就让我带你一探究竟,揭开小米...
安卓7.0系统线刷包,深度解析... 你有没有发现,你的安卓手机最近有点儿“蔫儿”了?别急,别急,今天就来给你揭秘如何让你的安卓手机重焕生...
白菜系统和安卓拍照,开启智能生... 你知道吗?最近我在用手机拍照的时候,发现了一个超级酷的功能,简直让我爱不释手!那就是——白菜系统和安...
安卓系统查杀病毒,全方位守护您... 手机里的安卓系统是不是有时候会突然弹出一个查杀病毒的提示?别慌,这可不是什么大问题,今天就来给你详细...
iso系统与安卓各系统哪个好,... 你有没有想过,手机操作系统就像是我们生活中的不同交通工具,各有各的特色和优势。今天,咱们就来聊聊这个...
中柏怎么换安卓系统,解锁更多可... 你有没有发现,中柏的安卓系统有时候用起来还挺不顺手的?别急,今天就来手把手教你如何给中柏手机升级安卓...