给定一个长度为N的数组arr[] ,任务是找到具有给定OR值M的子集数。
例子:
Input: arr[] = {2, 3, 2} M = 3
Output: 4
All possible subsets and there OR values are:
{2} = 2
{3} = 3
{2} = 2
{2, 3} = 2 | 3 = 3
{3, 2} = 3 | 2 = 3
{2, 2} = 2 | 2 = 2
{2, 3, 2} = 2 | 3 | 2 = 3
Input: arr[] = {1, 3, 2, 2}, M = 5
Output: 0
方法:一个简单的方法是通过生成所有可能的子集,然后通过给定 OR 值计算子集的数量来解决问题。但是,对于较小的数组元素值,可以使用动态规划来解决。
我们先来看递归关系。
dp[i][curr_or] = dp[i + 1][curr_or] + dp[i + 1][curr_or | arr[i]]
上面的递推关系可以定义为子数组arr[i…N-1]的子集数,这样与curr_or进行 OR 运算将产生所需的 OR 值。
因为只有路径,所以递归关系是合理的。或者,获取当前元素并将其与curr_or或忽略它并继续前进。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
#define maxN 20
#define maxM 64
// To store states of DP
int dp[maxN][maxM];
bool v[maxN][maxM];
// Function to return the required count
int findCnt(int* arr, int i, int curr, int n, int m)
{
// Base case
if (i == n) {
return (curr == m);
}
// If the state has been solved before
// return the value of the state
if (v[i][curr])
return dp[i][curr];
// Setting the state as solved
v[i][curr] = 1;
// Recurrence relation
dp[i][curr]
= findCnt(arr, i + 1, curr, n, m)
+ findCnt(arr, i + 1, (curr | arr[i]), n, m);
return dp[i][curr];
}
// Driver code
int main()
{
int arr[] = { 2, 3, 2 };
int n = sizeof(arr) / sizeof(int);
int m = 3;
cout << findCnt(arr, 0, 0, n, m);
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG
{
static int maxN = 20;
static int maxM = 64;
// To store states of DP
static int [][]dp = new int[maxN][maxM];
static boolean [][]v = new boolean[maxN][maxM];
// Function to return the required count
static int findCnt(int[] arr, int i,
int curr, int n, int m)
{
// Base case
if (i == n)
{
return (curr == m ? 1 : 0);
}
// If the state has been solved before
// return the value of the state
if (v[i][curr])
return dp[i][curr];
// Setting the state as solved
v[i][curr] = true;
// Recurrence relation
dp[i][curr] = findCnt(arr, i + 1, curr, n, m) +
findCnt(arr, i + 1, (curr | arr[i]), n, m);
return dp[i][curr];
}
// Driver code
public static void main(String []args)
{
int arr[] = { 2, 3, 2 };
int n = arr.length;
int m = 3;
System.out.println(findCnt(arr, 0, 0, n, m));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 implementation of the approach
import numpy as np
maxN = 20
maxM = 64
# To store states of DP
dp = np.zeros((maxN, maxM));
v = np.zeros((maxN, maxM));
# Function to return the required count
def findCnt(arr, i, curr, n, m) :
# Base case
if (i == n) :
return (curr == m);
# If the state has been solved before
# return the value of the state
if (v[i][curr]) :
return dp[i][curr];
# Setting the state as solved
v[i][curr] = 1;
# Recurrence relation
dp[i][curr] = findCnt(arr, i + 1, curr, n, m) + \
findCnt(arr, i + 1, (curr | arr[i]), n, m);
return dp[i][curr];
# Driver code
if __name__ == "__main__" :
arr = [ 2, 3, 2 ];
n = len(arr);
m = 3;
print(findCnt(arr, 0, 0, n, m));
# This code is contributed by AnkitRai01
C#
// C# implementation of the approach
using System;
class GFG
{
static int maxN = 20;
static int maxM = 64;
// To store states of DP
static int [,]dp = new int[maxN, maxM];
static Boolean [,]v = new Boolean[maxN, maxM];
// Function to return the required count
static int findCnt(int[] arr, int i,
int curr, int n, int m)
{
// Base case
if (i == n)
{
return (curr == m ? 1 : 0);
}
// If the state has been solved before
// return the value of the state
if (v[i, curr])
return dp[i, curr];
// Setting the state as solved
v[i, curr] = true;
// Recurrence relation
dp[i, curr] = findCnt(arr, i + 1, curr, n, m) +
findCnt(arr, i + 1, (curr | arr[i]), n, m);
return dp[i, curr];
}
// Driver code
public static void Main(String []args)
{
int []arr = { 2, 3, 2 };
int n = arr.Length;
int m = 3;
Console.WriteLine(findCnt(arr, 0, 0, n, m));
}
}
// This code is contributed by Rajput-Ji
Javascript
输出
4
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。