Given an array of length n, find the number of subsets, where the XOR of the subset is equal to the given number

For an array arrof length nfind many subsets arrexist so that XOR(^)these subsets is equal to a given number, ans.

I have this approach dp, but there is a way to improve its temporal complexity. ansalways less than 1024.

Here ans- no. such that the XOR(^)subsets are equal to it. arr[n]contains all numbers

memset(dp, 0, sizeof(dp));
dp[0][0] = 1;

for(i = 1; i <= n; i++){
    for(j = 0; j < 1024; j++) {
        dp[i][j] = (dp[i-1][j] + dp[i-1][j^arr[i]]);
    }
}

cout << (dp[n][ans]);
+2
source share
2 answers

From user3386109 comment built on top of the code:

/* Warning: Untested */
int counts[1024] = {0}, ways[1024];
for(int i = 1; i <= n; ++i) counts[ arr[i] ] += 1;
for(int i = 0; i <= 1024; ++i) {
  const int z = counts[i];
  // Look for overflow here
  ways[i] = z == 0 ?
              0 :
              (int)(1U << (z-1));
}

memset(dp, 0, sizeof(dp));
dp[0][0] = 1;

for(i = 1; i <= 1024; i++){
    for(j = 0; j < 1024; j++) {
        // Check for overflow
        const int howmany = ways[i] * dp[i-1][j];
        dp[i][j] += howmany;
        dp[i][j^i] += howmany;
    }
}

cout << (dp[1024][ans]);

odd_ even_ :

n c 0 + n c 2 +... = n c 1 + n c 3... = 2 -1

= =

, 2 dp ​​ , dp[i-2][x] .

+2

, (1) (2) , .

, solve(arr, n, ans) , ans < 1024, n < 1000000 arr = array[n]. dp[n][ans], , , dp dp = array[n+1][1024]. . , memset(dp, -1, sizeof(dp)), , dp[0][0] = 1

solve(arr, n, ans):
    if (dp[n][ans] == -1)
        if (n == 0) // and ans != 0 since that was initialized already
            dp[n][ans] = 0
        else
            // combine results with current and without current array element
            dp[n][ans] = solve(arr + 1, n - 1, ans) + solve(arr + 1, n - 1, ans XOR arr[0])
    return dp[n][ans]

, dp , .

n

+1

Source: https://habr.com/ru/post/1618915/


All Articles