算法笔记-- 二进制集合枚举子集 && 求子集和 && 求父集和
枚举子集:
复杂度:O(3^k)
for (int i = s; i; i = (i-1)&s);
用sos dp求解子集和以及父集和
子集和:
for (int i = 0; i <= k; i++) { for (int mask = 0; mask < (1<<k); mask++) { if(i == 0) {dp[mask][i] = cnt[mask]; continue;} if(mask&(1<<i)) dp[mask][i] = dp[mask^(1<<i)][i-1] + dp[mask][i-1]; else dp[mask][i] = dp[mask][i-1]; } }
父集和:
转移方向与上相反,优化一维空间
for (int mask = 0; mask < (1<<k); mask++) dp[mask] = cnt[mask]; for (int i = 0; i <= k; i++) { for (int mask = 0; mask < (1<<k); mask++) { if(mask&(1<<i)) dp[mask^(1<<i)] += dp[mask]; } }