📌  相关文章
📜  重新排列数组以最大化与另一个数组相同索引元素的按位与的总和

📅  最后修改于: 2021-09-07 02:26:30             🧑  作者: Mango

给定两个大小为N 的数组A[]B[] ,任务是找到数组A[]B[]中相同索引元素的按位与的最大和,可以通过重新排列获得 数组B[]以任何顺序。

例子:

朴素的方法:解决问题的最简单的方法是生成数组B[] 的所有可能排列,对于每个排列,计算数组A[]B[]中相同索引元素的按位与的总和并更新最大值可能的总和。最后,打印可能的最大和。

时间复杂度: O(N! * N)
辅助空间: O(1)

高效的方法:上述方法也可以基于以下观察进行优化:

请按照以下步骤解决问题:

  • 定义一个向量向量表示维度为N*2 N 的dp ,值为-1以存储所有 dp 状态。
  • 定义一个递归 Dp函数say maximumAndUtil(i, mask)以找到两个数组A[]B[]中相同位置的元素的按位与的最大和:
    • 基本情况,如果i等于N则返回0
    • 如果dp[i][mask]不等于-1,即已经访问过,则返回dp[i][mask]。
    • 使用变量j在范围[0, N-1] 上迭代,并且在每次迭代中,如果掩码中的j位未设置,则将dp[i][mask]更新为dp[i][mask] = max(dp[ i][掩码], maximizeUtil(i+1, mask| 2 j )。
    • 最后,返回dp[i][mask]。
  • 调用递归函数maximumAnd(0, 0)并打印它返回的值作为答案。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to implement recursive DP
int maximizeAnd(int i, int mask,
                int* A, int* B, int N,
                vector >& dp)
{
    // If i is equal to N
    if (i == N)
        return 0;
 
    // If dp[i][mask] is not
    // equal to -1
    if (dp[i][mask] != -1)
        return dp[i][mask];
 
    // Iterate over the array B[]
    for (int j = 0; j < N; ++j) {
 
        // If current element
        // is not yet selected
        if (!(mask & (1 << j))) {
 
            // Update dp[i][mask]
            dp[i][mask] = max(
                dp[i][mask],
                (A[i] & B[j])
                    + maximizeAnd(i + 1, mask | (1 << j), A,
                                  B, N, dp));
        }
    }
    // Return dp[i][mask]
    return dp[i][mask];
}
 
// Function to obtain maximum sum
// of Bitwise AND of same-indexed
// elements from the arrays A[] and B[]
int maximizeAndUtil(int* A, int* B, int N)
{
    // Stores all dp-states
    vector > dp(
        N, vector(1 << N + 1, -1));
 
    // Returns the maximum value
    // returned by the function maximizeAnd()
    return maximizeAnd(0, 0, A, B, N, dp);
}
 
// Driver Code
int main()
{
    int A[] = { 3, 5, 7, 11 };
    int B[] = { 2, 6, 10, 12 };
    int N = sizeof A / sizeof A[0];
 
    cout << maximizeAndUtil(A, B, N);
}


Java


Python3


输出:
22

时间复杂度: O (N 2 * 2 N)
辅助空间: O(N * 2 N )

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live