算法笔记-- 二进制集合枚举子集 && 求子集和 && 求父集和

枚举子集:

复杂度: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];
    }
}
原文地址:https://www.cnblogs.com/widsom/p/10309472.html