📜  通过切换相邻位,两个阵列的最大乘积和

📅  最后修改于: 2021-05-25 04:28:34             🧑  作者: Mango

给定相同大小的整数数组arr1和二进制数组arr2 ,任务是找到这些数组的乘积的最大可能和,即(arr1 [0] * arr2 [0])+(arr1 [1] * arr2 [ 1])+…..(arr1 [N-1] * arr2 [N-1])通过切换数组arr2中的任意两个相邻位获得。此切换次数可以无限次。

数组arr2中2个相邻位的切换如下:

  • 00切换到11
  • 01切换到10
  • 10切换到01
  • 11切换到00

例子:

Input: arr1 = {2, 3, 1}, arr2 = {0, 0, 1}
Output: 6
Explanation:
if we put 1 corresponding to a positive integer
then arr2 will be {1, 1, 1}
No. of 1's initially and now are odd
It means parity is same 
so this arrangement is fine
Hence sum will be 2 + 3 + 1 = 6.

Input: arr1 = {2, -4, 5, 3}, arr2 = {0, 1, 0, 1}
Output: 8

方法 :

  • 每次操作后,奇偶校验保持不变,即不。如果最初是偶数,则1的个数是偶数;如果最初是奇数,则1的奇数是奇数。
  • 第二个观察结果是,可以通过从第i个位切换来完成第i个和第j个位的切换,例如(i,i + 1),(i + 1,i + 2)…。 (j-1,j)在这里,每个位都切换两次(如果位被切换两次,则返回其初始值),除了i和j之外,最终第i个和第j个位切换。
  • 从这两个观察结果可以看出,我们可以在数组arr2中进行1和0的任何排列。我们唯一需要注意的是1和0的奇偶性。最终奇偶校验必须与初始奇偶校验相同。
  • 要获得最大总和,如果arr1中位于第i个位置的元素为正,则将1置于arr2的第i个位置,否则置0。

下面是上述方法的实现:

C++
// C++ program to find the maximum SoP of two arrays
// by toggling adjacent bits in the second array
  
#include 
using namespace std;
  
// Function to return Max Sum
int maxSum(int arr1[], int arr2[], int n)
{
    // intialParity and finalParity are 0
    // if total no. of 1's is even else 1
    int initialParity = 0, finalParity = 0;
  
    // minPositive and maxNegative will store
    // smallest positive and smallest negative
    // integer respectively.
    int sum = 0,
        minPositive = INT_MAX,
        maxNegative = INT_MIN;
  
    for (int i = 0; i < n; i++) {
  
        // Count of Initial Parity
        initialParity += arr2[i];
  
        // if arr1[i] is positive then add 1
        // in finalParity to get 1 at arr2[i]
        if (arr1[i] >= 0) {
  
            finalParity += 1;
            sum += arr1[i];
            minPositive = min(minPositive, arr1[i]);
        }
        else {
            maxNegative = max(maxNegative, arr1[i]);
        }
    }
  
    // if both parity are odd or even
    // then return sum
    if (initialParity % 2 == finalParity % 2) {
        return sum;
    }
  
    // else add one more 1 or remove 1
    else {
  
        // if minPositive > maxNegative,
        // put 1 at maxNegative
        // and add it to our sum
        if (minPositive + maxNegative >= 0) {
  
            return sum + maxNegative;
        }
  
        // else remove minPositive no.
        else {
  
            return sum - minPositive;
        }
    }
}
  
// Driver code
int main()
{
    int arr1[] = { 2, -4, 5, 3 };
    int arr2[] = { 0, 1, 0, 1 };
  
    int n = sizeof(arr1) / sizeof(arr1[0]);
    cout << maxSum(arr1, arr2, n) << endl;
  
    return 0;
}


Java
// Java program to find the maximum SoP 
// of two arrays by toggling adjacent bits 
// in the second array
class GFG
{
  
// Function to return Max Sum
static int maxSum(int arr1[], 
                  int arr2[], int n)
{
    // intialParity and finalParity are 0
    // if total no. of 1's is even else 1
    int initialParity = 0, finalParity = 0;
  
    // minPositive and maxNegative will store
    // smallest positive and smallest negative
    // integer respectively.
    int sum = 0,
        minPositive = Integer.MAX_VALUE,
        maxNegative = Integer.MIN_VALUE;
  
    for (int i = 0; i < n; i++)
    {
  
        // Count of Initial Parity
        initialParity += arr2[i];
  
        // if arr1[i] is positive then add 1
        // in finalParity to get 1 at arr2[i]
        if (arr1[i] >= 0)
        {
  
            finalParity += 1;
            sum += arr1[i];
            minPositive = Math.min(minPositive, 
                                      arr1[i]);
        }
        else
        {
            maxNegative = Math.max(maxNegative, 
                                      arr1[i]);
        }
    }
  
    // if both parity are odd or even
    // then return sum
    if (initialParity % 2 == finalParity % 2)
    {
        return sum;
    }
  
    // else add one more 1 or remove 1
    else
    {
  
        // if minPositive > maxNegative,
        // put 1 at maxNegative
        // and add it to our sum
        if (minPositive + maxNegative >= 0)
        {
            return sum + maxNegative;
        }
  
        // else remove minPositive no.
        else
        {
            return sum - minPositive;
        }
    }
}
  
// Driver code
public static void main(String []args)
{
    int arr1[] = { 2, -4, 5, 3 };
    int arr2[] = { 0, 1, 0, 1 };
  
    int n = arr1.length;
    System.out.println(maxSum(arr1, arr2, n));
}
}
  
// This code is contributed by 29AjayKumar


Python3
# Python3 program to find the 
# maximum SoP of two arrays by 
# toggling adjacent bits#
# in the second array
import sys
  
# Function to return Max Sum
def maxSum(arr1, arr2, n) :
  
    # intialParity and finalParity are 0
    # if total no. of 1's is even else 1
    initialParity, finalParity = 0, 0
  
    # minPositive and maxNegative will store
    # smallest positive and smallest negative
    # integer respectively.
    sum = 0
    minPositive = sys.maxsize
    maxNegative = -sys.maxsize - 1
  
    for i in range(n) :
  
        # Count of Initial Parity
        initialParity += arr2[i];
  
        # if arr1[i] is positive then add 1
        # in finalParity to get 1 at arr2[i]
        if (arr1[i] >= 0) :
  
            finalParity += 1
            sum += arr1[i]
            minPositive = min(minPositive, arr1[i])
  
        else :
            maxNegative = max(maxNegative, arr1[i])
          
    # if both parity are odd or even
    # then return sum
    if (initialParity % 2 == finalParity % 2) :
        return sum
  
    # else add one more 1 or remove 1
    else :
  
        # if minPositive > maxNegative,
        # put 1 at maxNegative
        # and add it to our sum
        if (minPositive + maxNegative >= 0) :
  
            return sum + maxNegative
  
        # else remove minPositive no.
        else :
  
            return sum - minPositive
  
# Driver code
arr1 = [ 2, -4, 5, 3 ]
arr2 = [ 0, 1, 0, 1 ]
  
n = len(arr1)
print(maxSum(arr1, arr2, n))
  
# This code is contributed by divyamohan123


C#
// C# program to find the maximum SoP 
// of two arrays by toggling adjacent bits 
// in the second array
using System;
                      
class GFG
{
  
// Function to return Max Sum
static int maxSum(int []arr1, 
                  int []arr2, int n)
{
    // intialParity and finalParity are 0
    // if total no. of 1's is even else 1
    int initialParity = 0, finalParity = 0;
  
    // minPositive and maxNegative will store
    // smallest positive and smallest negative
    // integer respectively.
    int sum = 0,
        minPositive = int.MaxValue,
        maxNegative = int.MinValue;
  
    for (int i = 0; i < n; i++)
    {
  
        // Count of Initial Parity
        initialParity += arr2[i];
  
        // if arr1[i] is positive then add 1
        // in finalParity to get 1 at arr2[i]
        if (arr1[i] >= 0)
        {
  
            finalParity += 1;
            sum += arr1[i];
            minPositive = Math.Min(minPositive, 
                                      arr1[i]);
        }
        else
        {
            maxNegative = Math.Max(maxNegative, 
                                      arr1[i]);
        }
    }
  
    // if both parity are odd or even
    // then return sum
    if (initialParity % 2 == finalParity % 2)
    {
        return sum;
    }
  
    // else add one more 1 or remove 1
    else
    {
  
        // if minPositive > maxNegative,
        // put 1 at maxNegative
        // and add it to our sum
        if (minPositive + maxNegative >= 0)
        {
            return sum + maxNegative;
        }
  
        // else remove minPositive no.
        else
        {
            return sum - minPositive;
        }
    }
}
  
// Driver code
public static void Main(String []args)
{
    int []arr1 = { 2, -4, 5, 3 };
    int []arr2 = { 0, 1, 0, 1 };
  
    int n = arr1.Length;
    Console.WriteLine(maxSum(arr1, arr2, n));
}
}
  
// This code is contributed by 29AjayKumar


输出:
8

时间复杂度:  O(n) ,其中n是数组的大小。