20200413(DEF)题解 by 孙晨曦

D、E、F题:孙晨曦

题解:

D题题解:组合数。
(直接选出来C(n,k)个位置,然后这k个位置取全排列的话,需要考虑去重,所以换个选法) 
这样做,先选出k个位置,然后只取让这k个位置都不能选择自己的indice的排列
例如,3个数,就只能选取231,312这两种排列。
经模拟得出1个数有0个这种排列,2个数有1个这种排列,3个数有2个,4个数有9个。
设个数组p[1]=0,p[2]=1,p[3]=2,p[4]=9
所以就可以得到,对于n,k,答案为
C(n,k)*p[k]+C(n,k-1)*p[k-1]+...+C(n,1)*p[1] +1
最后这个+1是因为以上过程没取从小到大顺序的这一种排列(1234567),所以要加上。。。思路挺简单,题解好像写的有点麻烦了

E题题解:折半搜索(meet in the middle)。
n=35,所以用折半搜索降低搜索的复杂度
用两个set存两次搜索的模m下的每个和
然后合并,更新最大值。
合并的方法是枚举第一个set的值(设为i),用upper_bound从第二个set中找第一个大于m-1-i的位置,有种情况:
①如果这个位置是set2.begin()的话,就说明set2中每个数加上i,都比m大,都要取余,那么set2中加i模m的值最大的数应该是set2中最后一个数,即取[set2.end()-1]的位置上的那个数。
②如果不是set2的首位置,那么set2中加i模m的最大值应该就是[这个位置-1]的位置上的那个数。

20200413(DEF)题解 by 孙晨曦
(下面是折半搜索的详解和两个例题)
20200413(DEF)题解 by 孙晨曦https://blog.csdn.net/qq_45530271/article/details/104239624

20200413(DEF)题解 by 孙晨曦

 

上一篇:【代码分享】用redis+lua实现多个集合取交集并过滤,类似于: select key from set2 where key in (select key from set1) and value


下一篇:java Set接口