组合、子集问题汇总

来源:互联网 发布:烯牛数据公司地址 编辑:程序博客网 时间:2024/06/05 06:25

子集的问题的思路也分两个方向,一种是解空间树是关于每个数选还是不选,结点取值范围就是true or false。解向量的长度是固定的,即candidates的个数,而且只有完全解才是问题的解。解向量不是直接的答案,而是标志每个candidates选还是不选。答案需要另一个向量根据搜索的路径填充。第二种思路是解空间树直接就是选取candidates。结点的取值范围就是可选的candidates,每个部分解都是问题的解。

对于有重复的情况,第二种思路好处理一些,和排列的去重类似,拿当前candidate跟当前层次取值范围已取过的比(如果是排序的,只需要跟取值范围内前一个比),有重复就continue。理由是,当前candidate的结果包含在之前candidate的结果里,因为本层的选择大家值一样,而之前的candidate的后面部分包含了当前candidate的后面部分。最新结论:有重复的情况,这种思路必须预先排序!

对于第一种思路的去重,方法类似多重背包问题反过来,把多个相同的数合并成一个数可被选择的次数。剪枝条件比01子集问题多了一个条件,即,“选”的分支加上一个条件判断可选的次数是否大于0。

对于一般组合问题,即从m个选n个,两种思路的退出条件一致,都是在最开始判断selectedIndex>=n,即是否已选了n个。对于第一种思路,之前的退出条件t>=m就不用了,因为selectedIndex>=n的条件更严。如果已选够了,即便还有candidate没有看也不用看了,因为肯定不能选。

0 0
原创粉丝点击