// C# implementation to find Max OR of
// subsequence of size k using Memoization
using System;
using System.Collections.Generic;
class GfG {
// Helper function with memoization
static int MaxOrHelper(List<int> arr, int n, int k,
int index, int currOR, int currSize,
int[,,] memo) {
// If we have selected k elements, return
// the current OR value
if (currSize == k) {
return currOR;
}
// If we have exhausted all elements
if (index == n) {
return 0;
}
// Check if the result is already computed
if (memo[index, currSize, currOR] != -1) {
return memo[index, currSize, currOR];
}
// Include the current element and recurse
int include = MaxOrHelper(arr, n, k, index + 1,
currOR | arr[index],
currSize + 1, memo);
// Skip the current element and recurse
int exclude = MaxOrHelper(arr, n, k, index + 1,
currOR, currSize, memo);
// Store the result in the memoization table
memo[index, currSize, currOR] = Math.Max(include, exclude);
return memo[index, currSize, currOR];
}
static int MaxOrK(List<int> arr, int k) {
int n = arr.Count;
// Create a memoization table with dimensions [n][k+1]
// [maximum possible OR value]
int maxPossibleOR = 0;
foreach (int num in arr) {
maxPossibleOR |= num;
}
// Create a 3D memo table, initializing all values
// as -1
int[,,] memo = new int[n + 1, k + 1, maxPossibleOR + 1];
// Initialize the memo table with -1
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= k; j++) {
for (int l = 0; l <= maxPossibleOR; l++) {
memo[i, j, l] = -1;
}
}
}
return MaxOrHelper(arr, n, k, 0, 0, 0, memo);
}
static void Main() {
List<int> arr = new List<int> { 2, 5, 3, 6, 11, 13 };
int k = 3;
Console.WriteLine(MaxOrK(arr, k));
}
}