昨晚做srm,花了很长时间把div2 1000做了。也算没有白熬夜。。
题意:
有n块石头,每块石头的重量分别是W1 W2 ... Wn。现在有能装重量为cap的石头的背包m个。问最多可以装多少石头。
其中 n <= 13 , m <= 10, Wi以及cap都小于等于20。
思考过程:
贪心是不对的。每个背包里取的石头,大小不一定是连续的。比如 1 2 3 4 背包大小为5,则要1 4一个包,2 3一个包。
数据范围很小,选取的石头可以用二进制位表示。状态总数是1<<13。
那么要找的就是用m个背包,所能达到的石头数量最多的状态。
要解决m个背包的问题,先解决1个背包的问题。1个背包所能达到的不同的状态,可以通过枚举或搜索来得到。因为石头最多才13个。
然后解决m个背包的问题。m个背包,其实就是1个背包问题的叠加。由于最多只有10背包,所以搜索就可以解决m个背包的问题了。
这样问题就解决了。
注意:
单纯的搜索会超时。需要加一些优化。
在解决1个背包状态问题的时候,只需要保留那些"满的状态"。也就是说不能再放入其他任何一块石头的状态。
在解决m个背包状态问题的时候,可以进行记忆化。memo[x][bitmask]表示还剩下x个背包,并且已经选择了bitmask所表示的石头,所能得到的最优结果。其中bitmask表示的是选择的石头的二进制表示。
是一道好题。

