From Google Earth

Knapsack Cryptosystem

题意很简单,是说有一个排好序的升序正整数序列,现在给出总和s,让你从数列中挑出若干个数,使得它们相加后总和为s。

第一反应就是dfs,因为之前做过几乎一模一样的题,且这题数据范围很小,数列最长才36。但事实证明,dfs会T飞......无论怎么剪枝都没用。

正确解法是,将数列折半,对于前一半,状压枚举出每一种选取情况的总和,将它们存入一个map里面。对于后一半,依然是状压枚举每种选取情况的总和,记作\(s_i\),在算出\(s_i\)后,二分lower_bound()在map中找\(s-s_i\),如果找到了,就可以输出结果了,答案就是此时后半的选取情况以及\(s-s_i\)对应的前半选取情况。

代码如下: