Given an array of length n, find number of subsets where XOR of a subset is equal to a given number [closed]

不打扰是莪最后的温柔 提交于 2019-11-29 12:19:05
Mohit Jain

From user3386109's comment, building on top of your 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]);

For calculating odd_ and even_, you can also use the following:

nc0+nc2+... = nc1+nc3... = 2n-1

Because number of ways to select odd items = number of ways to reject odd items = number of ways to select even numbers

You can also optimize the space by keeping just 2 columns of dp arrays and reusing them as dp[i-2][x] are discarded.

The Idea behind dynamic programming is, to (1) never compute the same result twice and (2) only compute results at demand and not precompute the whole thing as you do it.

So there is a solution needed for solve(arr, n, ans) with ans < 1024, n < 1000000 and arr = array[n]. The idea of having dp[n][ans] holding the number of results is reasonable, so dp size is needed as dp = array[n+1][1024]. What we need is a way to distinguish between not yet computed results and available results. So memset(dp, -1, sizeof(dp)) and then as you already did 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]

The advantage is, that your dp array is only partially computed on the way to your solution, so this might save some time.

Depending on the stack size and n, it might be necessary to translate this from a recursive to an iterative solution

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!