📜  数数特定XOR值的有序子集

📅  最后修改于: 2021-04-26 07:39:12             🧑  作者: Mango

给定n个元素的数组arr []和数K ,找到元素XOR为Karr []的有序子集数
这是此问题的修改后的版本。因此,建议您先尝试该问题。

例子:

天真的方法O(2 n ):生成所有2 n个子集,并找到所有具有XOR值K的子集,并为每个具有XOR值K的子集添加no。子集对答案的排列,因为我们需要有序子集,但是这种方法对于n较大的值将无效。

高效方法O(n 2 * m):此方法使用动态编程,与本文介绍的方法相似。
唯一的修改是我们在解决方案中增加了一个状态。那里有两个状态,其中dp [i] [j]存储了否。 XOR值为j数组[0…i-1]的子集的数量。现在,我们再添加一个状态k ,即存储子集长度的第三维。
因此, dp [i] [j] [k]将存储编号。具有XOR值j数组[0…i-1]的长度k的子集的集合。

现在我们可以看到

     $$ dp[i][j][k] = dp[i-1][j][k] + k*dp[i-1][a[i-1] XOR j][k-1] $$

dp [i] [j] [k]可以通过丢弃a [i]元素(给出dp [i-1] [j] [k]子集)并将其放入子集中来找到(与子集相似)求和问题)给出dp [i-1] [a [i] ^ j] [k-1]个子集。现在我们必须在k – 1个长度子集中插入a [i]元素,这可以用k种方式来完成,这可以解释k的因数。

换上dp阵列后,我们的答案将是

 $ \sum_{k=1}^{k=n} dp[n][K][k] $

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
  
// Returns count of ordered subsets of arr[]
// with XOR value = K
int subsetXOR(int arr[], int n, int K)
{
  
    // Find maximum element in arr[]
    int max_ele = arr[0];
    for (int i = 1; i < n; i++)
        if (arr[i] > max_ele)
            max_ele = arr[i];
  
    // Maximum possible XOR value
    int m = (1 << (int)(log2(max_ele) + 1)) - 1;
  
    // The value of dp[i][j][k] is the number 
    // of subsets of length k having XOR of their 
    // elements as j from the set arr[0...i-1]
    int dp[n + 1][m + 1][n + 1];
  
    // Initializing all the values of dp[i][j][k]
    // as 0
    for (int i = 0; i <= n; i++)
        for (int j = 0; j <= m; j++)
            for (int k = 0; k <= n; k++)
                dp[i][j][k] = 0;
  
    // The xor of empty subset is 0
    for (int i = 0; i <= n; i++)
        dp[i][0][0] = 1;
  
    // Fill the dp table
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= m; j++) {
            for (int k = 0; k <= n; k++) {
                dp[i][j][k] = dp[i - 1][j][k];
                if (k != 0) {
                    dp[i][j][k] += k * dp[i - 1][j ^ 
                                   arr[i - 1]][k - 1];
                }
            }
        }
    }
  
    // The answer is the number of subsets of all lengths
    // from set arr[0..n-1] having XOR of elements as k
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        ans += dp[n][K][i];
    }
    return ans;
}
  
// Driver program to test above function
int main()
{
    int arr[] = { 1, 2, 3 };
    int k = 1;
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << subsetXOR(arr, n, k);
    return 0;
}


Java
// Java implementation of the approach
import java.util.*;
  
class GFG
{
    // Returns count of ordered subsets of arr[]
    // with XOR value = K
    static int subsetXOR(int arr[], int n, int K)
    {
      
        // Find maximum element in arr[]
        int max_ele = arr[0];
        for (int i = 1; i < n; i++)
            if (arr[i] > max_ele)
                max_ele = arr[i];
      
        // Maximum possible XOR value
        int m = (1 << (int)(Math.log(max_ele) / 
                        Math.log(2) + 1)) - 1;
      
        // The value of dp[i][j][k] is the number 
        // of subsets of length k having XOR of their 
        // elements as j from the set arr[0...i-1]
        int [][][] dp = new int[n + 1][m + 1][n + 1];
      
        // Initializing all the values of 
        // dp[i][j][k] as 0
        for (int i = 0; i <= n; i++)
            for (int j = 0; j <= m; j++)
                for (int k = 0; k <= n; k++)
                    dp[i][j][k] = 0;
      
        // The xor of empty subset is 0
        for (int i = 0; i <= n; i++)
            dp[i][0][0] = 1;
      
        // Fill the dp table
        for (int i = 1; i <= n; i++) 
        {
            for (int j = 0; j <= m; j++) 
            {
                for (int k = 0; k <= n; k++) 
                {
                    dp[i][j][k] = dp[i - 1][j][k];
                    if (k != 0)
                    {
                        dp[i][j][k] += k * dp[i - 1][j ^ 
                                    arr[i - 1]][k - 1];
                    }
                }
            }
        }
      
        // The answer is the number of subsets 
        // of all lengths from set arr[0..n-1]
        // having XOR of elements as k
        int ans = 0;
        for (int i = 1; i <= n; i++) 
        {
            ans += dp[n][K][i];
        }
        return ans;
    }
      
    // Driver code
    public static void main(String []args)
    {
        int arr[] = { 1, 2, 3 };
        int k = 1;
        int n = arr.length;
        System.out.println(subsetXOR(arr, n, k));
    }
}
  
// This code is contributed by ihritik


Python3
# Python 3implementation of the approach
from math import log2
  
# Returns count of ordered subsets of arr[]
# with XOR value = K
def subsetXOR(arr, n, K):
      
    # Find maximum element in arr[]
    max_ele = arr[0]
    for i in range(1, n):
        if (arr[i] > max_ele):
            max_ele = arr[i]
  
    # Maximum possible XOR value
    m = (1 << int(log2(max_ele) + 1)) - 1
  
    # The value of dp[i][j][k] is the number 
    # of subsets of length k having XOR of their 
    # elements as j from the set arr[0...i-1]
    dp = [[[0 for i in range(n + 1)] 
              for j in range(m + 1)] 
              for k in range(n + 1)]
  
    # Initializing all the values 
    # of dp[i][j][k] as 0
    for i in range(n + 1):
        for j in range(m + 1):
            for k in range(n + 1):
                dp[i][j][k] = 0
  
    # The xor of empty subset is 0
    for i in range(n + 1):
        dp[i][0][0] = 1
  
    # Fill the dp table
    for i in range(1, n + 1):
        for j in range(m + 1):
            for k in range(n + 1):
                dp[i][j][k] = dp[i - 1][j][k]
                if (k != 0):
                    dp[i][j][k] += k * dp[i - 1][j ^ arr[i - 1]][k - 1]
  
    # The answer is the number of subsets of all lengths
    # from set arr[0..n-1] having XOR of elements as k
    ans = 0
    for i in range(1, n + 1):
        ans += dp[n][K][i]
      
    return ans
  
# Driver Code
if __name__ == '__main__':
    arr = [1, 2, 3]
    k = 1
    n = len(arr)
    print(subsetXOR(arr, n, k))
      
# This code is contributed by
# Surendra_Gangwar


C#
// C# implementation of the approach
using System;
  
class GFG
{
    // Returns count of ordered subsets of arr[]
    // with XOR value = K
    static int subsetXOR(int []arr, int n, int K)
    {
      
        // Find maximum element in arr[]
        int max_ele = arr[0];
        for (int i = 1; i < n; i++)
            if (arr[i] > max_ele)
                max_ele = arr[i];
      
        // Maximum possible XOR value
        int m = (1 << (int)(Math.Log(max_ele) / 
                        Math.Log(2) + 1)) - 1;
      
        // The value of dp[i][j][k] is the number 
        // of subsets of length k having XOR of their 
        // elements as j from the set arr[0...i-1]
        int [ , , ] dp = new int[n + 1 , m + 1 ,n + 1];
      
        // Initializing all the values of 
        // dp[i][j][k] as 0
        for (int i = 0; i <= n; i++)
            for (int j = 0; j <= m; j++)
                for (int k = 0; k <= n; k++)
                    dp[i, j, k] = 0;
      
        // The xor of empty subset is 0
        for (int i = 0; i <= n; i++)
            dp[i, 0, 0] = 1;
      
        // Fill the dp table
        for (int i = 1; i <= n; i++) 
        {
            for (int j = 0; j <= m; j++)
            {
                for (int k = 0; k <= n; k++)
                {
                    dp[i, j, k] = dp[i - 1, j, k];
                    if (k != 0) {
                        dp[i, j, k] += k * dp[i - 1, j ^ 
                                    arr[i - 1], k - 1];
                    }
                }
            }
        }
      
        // The answer is the number of subsets 
        // of all lengths from set arr[0..n-1] 
        // having XOR of elements as k
        int ans = 0;
        for (int i = 1; i <= n; i++) 
        {
            ans += dp[n, K, i];
        }
        return ans;
    }
      
    // Driver code
    public static void Main()
    {
        int []arr = { 1, 2, 3 };
        int k = 1;
        int n = arr.Length;
        Console.WriteLine(subsetXOR(arr, n, k));
    }
}
  
// This code is contributed by ihritik


PHP
 $max_ele) 
            $max_ele = $arr[$i]; 
  
    // Maximum possible XOR value 
    $m = (1 << (floor(log($max_ele, 2))+ 1)) - 1; 
  
    // The value of dp[i][j][k] is the number 
    // of subsets of length k having XOR of their 
    // elements as j from the set arr[0...i-1] 
    $dp = array(array(array())) ;
  
    // Initializing all the values 
    // of dp[i][j][k] as 0 
    for ($i = 0; $i <= $n; $i++) 
        for ($j = 0; $j <= $m; $j++) 
            for ($k = 0; $k <= $n; $k++) 
                $dp[$i][$j][$k] = 0; 
  
    // The xor of empty subset is 0 
    for ($i = 0; $i <= $n; $i++) 
        $dp[$i][0][0] = 1; 
  
    // Fill the dp table 
    for ($i = 1; $i <= $n; $i++)
    { 
        for ($j = 0; $j <= $m; $j++) 
        { 
            for ($k = 0; $k <= $n; $k++) 
            { 
                $dp[$i][$j][$k] = $dp[$i - 1][$j][$k]; 
                if ($k != 0) 
                { 
                    $dp[$i][$j][$k] += $k * $dp[$i - 1][$j ^
                                       $arr[$i - 1]][$k - 1]; 
                } 
            } 
        } 
    } 
  
    // The answer is the number of subsets 
    // of all lengths from set arr[0..n-1] 
    // having XOR of elements as k 
    $ans = 0; 
    for ($i = 1; $i <= $n; $i++) 
    { 
        $ans += $dp[$n][$K][$i]; 
    } 
    return $ans; 
} 
  
// Driver Code
$arr = [ 1, 2, 3 ]; 
$k = 1; 
$n = sizeof($arr); 
echo subsetXOR($arr, $n, $k); 
  
// This code is contributed by Ryuga
?>


输出:
3