按包含排除计算

时间:2017-03-17 21:13:47

标签: dynamic-programming bitmask

任何人都请帮我弄清楚hackerrank蜡烛计数问题中使用的位掩码(包含 - 排除原理方法) https://www.hackerrank.com/challenges/candles-2
我无法清楚地了解编辑代码中的内容。 你可以打开完整代码的社论

int res = 0;
for(int mask = 0; mask < (1 << K); mask ++){
    memset(ft, 0, sizeof ft);
    int tmp = 0;
    for(int i = 0; i < N; i++){
        if((mask >> (C[i] - 1)) & 1){
            dp[i] = 1 + query(H[i] - 1); // BIT Query function
            madd(tmp, dp[i]);
            update(H[i], dp[i]); // BIT update function
        }
    }
    if(__builtin_popcount(mask) % 2 == K % 2){
        madd(res, tmp);
    } else {
        madd(res, mod - tmp);
    }
}

1 个答案:

答案 0 :(得分:0)

以下是我从你发布的代码中可以得出的结果 -

1) if((mask >> (C[i] - 1)) & 1)检查i蜡烛颜色的颜色是否已经存在(假设遮罩用于存储已经使用过的颜色在代码中没有意义)

2) query(H[i] - 1)返回可以从所有以前的蜡烛形成的子序列的数量,因为它们都将是彩色的,因为当前蜡烛是第一个具有重复颜色的蜡烛,因此如果它被排除我们得到'多彩的子序列'。

3) update(H[i], dp[i]);用于删除所有不需要的蜡烛。

示例 - 如果我们的序列按顺序具有以下颜色 - 2 3 1 4 5 6 1 7 8 然后当我们到达第二个'1'时,阵列中存储的颜色将只有4 5 6 1,即'2 3 1'将被删除,'7 8'将被读取。

4) madd(tmp, dp[i]);您的代码中的数据不足抱歉

5) __builtin_popcount(mask)计算掩码中的数量。