状态压缩技巧

枚举当前集合的子集        

	for(int j = i ; j ; j = (j - 1) & i);

其中 i 表示为当前所取物品的状态。下面验证其正确性:

j = j - 1 的逻辑意义表示 j 从右往左数第一个1变为0,而这个1之后的0都变为1 。例如:11000 - 1 = 10111 。而他的现实意义则表示了右边第一个取的物品不取了,在这个物品右边的物品全取。这自然包含了所有可能的集合,因此完备性得以保证。& i 操作的保证了j 是 i 的子集,因此正确性得以保证。

枚举当前集合的超集

for(int j = i ; j ; j = (j + 1) | i){if(j == (1 << n) - 1){//取到最大值退出break;}}

同样验证其正确性:

j = j + 1 能够枚举出所有大于j的集合,要保证i \in j 则必然有j > i 。因此完备性得以保证。同样的,| i 操作能够保证 j 一定包含了i , 即i \in j,因此正确性得以保证。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部