每日总结2021.4.25

1.洛谷 Balanced Cow Subsets G 看题解都看了一下午,直接原地裂开。但确实收获了很多。

大意 给你n 个数(2<=n<=20)从这些数里面选若干个,分成两组,是两组的和相等,问有多少种选法。

做法1:思路:一看数据范围,自然想到搜索,然后呢?然后。。。不会了,暴力搜索肯定不行,会超时。因为要考虑分到A组,B组,和哪个组都不分三种情况 3的20次方!! 告辞!

看了一下午题解之后: 首先直接搜肯超时,也没什么好的剪枝策略(反正题解没),所以想到用双向DFS。

首先想一下直接搜索是怎么处理? 对于每个节点,有三个分支:不选,分到A组,分到B组。我们怎么简单的表示出A组和B组的值是否相等呢?如果真去一点点的去模拟纪录A组B组的和,先不说能不能纪录,但肯定不好记录?!!A对B的相对值!!!对于A来说,分到A组就是在原来的基础上+x,分到B组,就是B组+x,站在A组的角度就是相对于B组 -x ,这样我们就可以很简单的表示出A,B两组是否相等,即看A相对于B的值,相对值为0,即A和B两组的和相等。(真巧妙)状态表示出来了,接下来就是进行双向DFS了。分为前半段和半段分开搜索,两段和为0的情况就行了。最后双指针扫描,进行两段匹配(前半段 与半段全不选的情况 匹配就是只看前半的情况,反之是只看后半段的情况,所以这样就把所有搜索节点不遗漏的搜索到了)!!但注意为了确保不会重复分组的情况,即前半段某部分分到A组,后半段某部分分到B组 和前半段那部分分到B组,后半段那部分分到A组是同一种情况,因为总是选的这些数。所以要判重。怎么判重呢?因为n不太大,状态压缩!所以要在搜索的时候纪录下选数的状态,压缩成二进制存下来。最后别忘了-1,因为全不选也是0。双指针扫描也存在很多小细节,因为每个半段搜索出来都可能有正有负嘛。把其中一个从小到大排序,另一个从大到小排可以更快的匹配。时间复杂度有点玄学:首先搜索 2*3的10次方约等于2e5;双指针扫描最坏情况前面半段搜索出来的值全部相等导致每次r从头开始,复杂度n方,但是这种情况不太可能出现,所有的都相等即不选,放A组,放B组的值相等,该数字为 0?不合题意,但不排除个别相等,所以说复杂度不太稳定,容易被卡。

做法2,用map进行离散化, 不开o2优化会被卡一个点。据说手写哈希表会快一些。因为不会写哈希表,就没有手写哈希表实现。思路明天补,害,今天要补作业了。

补更:注意n<=20,分成两组的和最多2的20次方,大约为1e6,可以接受,可以根据搜索结果来做,先把前半段的搜索结果记录下来,用map离散化处理,同时用vector存下来值和压缩后的选择状态。第二次搜索的时候边搜索边匹配,手写hash表可能效果更好一些。和做法1本质相同,做法1是两次搜索都先存下来,然后匹配。做法二是第二次搜索时边搜索边匹配。当然数据不太大的话,直接开数组纪录。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值