给定三个二进制字符串S1 , S2和S3,每个字符串的长度为N ,任务是找到可以通过重新排列给定字符串的字符而获得的最大可能的按位XOR。
例子:
Input: S1 = “1001”, S2 = “0010”, S3 = “1110”
Output: 15
Explanation:
Rearrange the digits of S1 as “1010”, S2 as “1000” and S3 as “1101”.
The XOR of these strings is “1111” which is 15 in decimal form.
Input: S1 = “11111”, S2 = “11111”, S3 = “11111”
Output: 31
Explanation:
There is no other way to arrange the digits. Hence, XOR is “11111” which is 31 in decimal form.
天真的方法:最简单的方法是生成所有可能的方法来重新排列S1 , S2和S3 。假设在字符串S1 , S2和S3中分别有O1 , O2和O3设置位。要获得最大按位XOR值,要检查的重排总数如下:
Total ways to rearrange S1 = NCO1
Total ways to rearrange S2 = NCO2
Total ways to rearrange S3 = NCO3
Hence, total possible rearrangements to check = NCO1*NCO2 * NCO3
时间复杂度: O((N!) 3 ),其中N是给定字符串的长度。
辅助空间: O(N)
高效的方法:想法是找到合适的S1 , S2和S3重排,以便使用动态编程使它们的按位XOR值最大化。子问题可以存储在dp [] [] [] []表中,其中dp [i] [o1] [o2] [o3]存储最大XOR值,从索引i开始直到位置N-1 ,其中o1是 , o2和o3是分别剩下要放置在字符串S1 , S2和S3中的1 s的数目。
从0到(N – 1)的任何位置i可能有四种情况:
- 给所有三个字符串分配1 s
- 将1 s分配给任意两个字符串
- 将1 s分配给任意一个字符串。
- 将0分配给所有字符串。
从上述每个位置的可能情况中,计算从四种可能性中可获得的最大按位异或:
请按照以下步骤解决问题:
- 初始化表dp [] [] [] []以存储位置i从0到N-1的S1 , S2和S3中的个数。
- 过渡状态如下:
dp[i][o1][o2][o3] = max(dp(assign 1s to all three strings), dp(assign 1s to any of the two strings), dp(assign 1s to any one string), dp(do not assign 1 to any string)) where,
i = current position
o1 = remaining ones to be placed in the string S1
o2 = remaining ones to be placed in the string S2
o3 = remaining ones to be placed in the string S3
- 使用上述转换解决所有情况的子问题,并在其中打印最大XOR值。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Dp table to store the sub-problems
int dp[20][20][20][20];
// Function to find the maximum XOR
// value after rearranging the digits
int maxXorValue(int i, string& s1,
string& s2, string& s3,
int ones1, int ones2,
int ones3, int n)
{
// Base Case
if (i >= n)
return 0;
// Return if already calculated
if (dp[i][ones1][ones2][ones3] != -1)
return dp[i][ones1][ones2][ones3];
int option1 = 0, option2 = 0,
option3 = 0, option4 = 0,
option5 = 0, option6 = 0,
option7 = 0, option8 = 0;
// Assigning 1's to all string at
// position 'i'.
if (ones1 > 0 && ones2 > 0
&& ones3 > 0)
// 2^(n-1-i) is the value
// added to the total
option1
= (1 << ((n - 1) - i))
+ maxXorValue(i + 1, s1,
s2, s3, ones1 - 1,
ones2 - 1,
ones3 - 1, n);
// Assigning 1's to strings 1 & 2
if (ones1 > 0 && ones2 > 0
&& (n - i > ones3))
option2
= 0
+ maxXorValue(i + 1, s1,
s2, s3, ones1 - 1,
ones2 - 1,
ones3, n);
// Assigning 1's to strings 2 & 3
if (ones2 > 0 && ones3 > 0
&& (n - i > ones1))
option3 = 0
+ maxXorValue(i + 1, s1,
s2, s3,
ones1,
ones2 - 1,
ones3 - 1, n);
// Assigning 1's to strings 3 & 1
if (ones3 > 0 && ones1 > 0
&& (n - i > ones2))
option4
= 0
+ maxXorValue(i + 1, s1,
s2, s3,
ones1 - 1,
ones2,
ones3 - 1, n);
// Assigning 1 to string 1
if (ones1 > 0 && (n - i > ones2)
&& (n - i > ones3))
option5 = (1 << ((n - 1) - i))
+ maxXorValue(i + 1, s1,
s2, s3,
ones1 - 1,
ones2,
ones3, n);
// Assigning 1 to string 2
if (ones2 > 0 && (n - i > ones3)
&& (n - i > ones1))
option6 = (1 << ((n - 1) - i))
+ maxXorValue(i + 1, s1,
s2, s3, ones1,
ones2 - 1,
ones3, n);
// Assigning 1 to string 3.
if (ones3 > 0 && (n - i > ones2)
&& (n - i > ones1))
option7 = (1 << ((n - 1) - i))
+ maxXorValue(i + 1, s1,
s2, s3, ones1,
ones2,
ones3 - 1, n);
// Assigning 0 to all the strings
if ((n - i > ones2) && (n - i > ones3)
&& (n - i > ones1))
option8 = 0
+ maxXorValue(i + 1, s1,
s2, s3,
ones1,
ones2,
ones3, n);
// Take the maximum amongst all of
// the above solutions
return dp[i][ones1][ones2][ones3]
= max(option1,
max(option2,
max(option3,
max(option4,
max(option5,
max(option6,
max(option7,
option8)))))));
}
// Function to get the count of ones
// in the string s
int onesCount(string& s)
{
int count = 0;
// Traverse the string
for (auto x : s) {
if (x == '1')
++count;
}
// Return the count
return count;
}
// Utility Function to find the maximum
// XOR value after rearranging the digits
void maxXORUtil(string s1, string s2,
string s3, int n)
{
// Find the count of ones in
// each of the strings
int ones1 = onesCount(s1);
int ones2 = onesCount(s2);
int ones3 = onesCount(s3);
// Initialize dp table with -1
memset(dp, -1, sizeof dp);
// Function Call
cout << maxXorValue(0, s1, s2, s3,
ones1, ones2,
ones3, n);
}
// Driver code
int main()
{
string s1 = "11110";
string s2 = "10101";
string s3 = "00111";
int n = s1.size();
// Function Call
maxXORUtil(s1, s2, s3, n);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
import java.lang.*;
class GFG{
// Dp table to store the sub-problems
static int[][][][] dp = new int[20][20][20][20];
// Function to find the maximum XOR
// value after rearranging the digits
static int maxXorValue(int i, String s1,
String s2, String s3,
int ones1, int ones2,
int ones3, int n)
{
// Base Case
if (i >= n)
return 0;
// Return if already calculated
if (dp[i][ones1][ones2][ones3] != -1)
return dp[i][ones1][ones2][ones3];
int option1 = 0, option2 = 0,
option3 = 0, option4 = 0,
option5 = 0, option6 = 0,
option7 = 0, option8 = 0;
// Assigning 1's to all string at
// position 'i'.
if (ones1 > 0 && ones2 > 0 &&
ones3 > 0)
// 2^(n-1-i) is the value
// added to the total
option1 = (1 << ((n - 1) - i)) +
maxXorValue(i + 1, s1, s2,
s3, ones1 - 1,
ones2 - 1,
ones3 - 1, n);
// Assigning 1's to strings 1 & 2
if (ones1 > 0 && ones2 > 0 &&
(n - i > ones3))
option2 = 0 + maxXorValue(i + 1, s1, s2,
s3, ones1 - 1,
ones2 - 1,
ones3, n);
// Assigning 1's to strings 2 & 3
if (ones2 > 0 && ones3 > 0 &&
(n - i > ones1))
option3 = 0 + maxXorValue(i + 1, s1, s2,
s3, ones1,
ones2 - 1,
ones3 - 1, n);
// Assigning 1's to strings 3 & 1
if (ones3 > 0 && ones1 > 0 &&
(n - i > ones2))
option4 = 0 + maxXorValue(i + 1, s1, s2,
s3, ones1 - 1,
ones2,
ones3 - 1, n);
// Assigning 1 to string 1
if (ones1 > 0 && (n - i > ones2) &&
(n - i > ones3))
option5 = (1 << ((n - 1) - i)) +
maxXorValue(i + 1, s1, s2,
s3, ones1 - 1,
ones2, ones3, n);
// Assigning 1 to string 2
if (ones2 > 0 && (n - i > ones3) &&
(n - i > ones1))
option6 = (1 << ((n - 1) - i)) +
maxXorValue(i + 1, s1,
s2, s3, ones1,
ones2 - 1,
ones3, n);
// Assigning 1 to string 3.
if (ones3 > 0 && (n - i > ones2) &&
(n - i > ones1))
option7 = (1 << ((n - 1) - i)) +
maxXorValue(i + 1, s1,
s2, s3, ones1,
ones2,
ones3 - 1, n);
// Assigning 0 to all the strings
if ((n - i > ones2) && (n - i > ones3) &&
(n - i > ones1))
option8 = 0 + maxXorValue(i + 1, s1,
s2, s3, ones1,
ones2, ones3, n);
// Take the maximum amongst all of
// the above solutions
return dp[i][ones1][ones2][ones3] =
Math.max(option1,
Math.max(option2,
Math.max(option3,
Math.max(option4,
Math.max(option5,
Math.max(option6,
Math.max(option7,
option8)))))));
}
// Function to get the count of ones
// in the string s
static int onesCount(String s)
{
int count = 0;
// Traverse the string
for(char x : s.toCharArray())
{
if (x == '1')
++count;
}
// Return the count
return count;
}
// Utility Function to find the maximum
// XOR value after rearranging the digits
static void maxXORUtil(String s1, String s2,
String s3, int n)
{
// Find the count of ones in
// each of the strings
int ones1 = onesCount(s1);
int ones2 = onesCount(s2);
int ones3 = onesCount(s3);
// Initialize dp table with -1
for(int[][][] i : dp)
for(int[][] j : i)
for(int[] k : j)
Arrays.fill(k, -1);
// Function Call
System.out.println(maxXorValue(0, s1, s2, s3,
ones1, ones2,
ones3, n));
}
// Driver code
public static void main (String[] args)
{
String s1 = "11110";
String s2 = "10101";
String s3 = "00111";
int n = s1.length();
// Function call
maxXORUtil(s1, s2, s3, n);
}
}
// This code is contributed by offbeat
Python3
# Python3 program for the
# above approach
# Dp table to store the
# sub-problems
dp = [[[[-1 for x in range(20)]
for y in range(20)]
for z in range(20)]
for p in range(20)]
# Function to find the maximum
# XOR value after rearranging
# the digits
def maxXorValue(i, s1, s2, s3,
ones1, ones2,
ones3, n):
# Base Case
if (i >= n):
return 0
# Return if already
#calculated
if (dp[i][ones1][ones2][ones3] != -1):
return dp[i][ones1][ones2][ones3]
option1 = 0
option2 = 0
option3 = 0
option4 = 0
option5 = 0
option6 = 0
option7 = 0
option8 = 0
# Assigning 1's to all
# string at position 'i'.
if (ones1 > 0 and ones2 > 0 and
ones3 > 0):
# 2^(n-1-i) is the value
# added to the total
option1 = ((1 << ((n - 1) - i)) +
maxXorValue(i + 1, s1,
s2, s3,
ones1 - 1,
ones2 - 1,
ones3 - 1, n))
# Assigning 1's to strings
# 1 & 2
if (ones1 > 0 and ones2 > 0 and
(n - i > ones3)):
option2 = (0 + maxXorValue(i + 1, s1,
s2, s3,
ones1 - 1,
ones2 - 1,
ones3, n))
# Assigning 1's to strings
# 2 & 3
if (ones2 > 0 and ones3 > 0 and
(n - i > ones1)):
option3 = (0 + maxXorValue(i + 1, s1,
s2, s3,
ones1,
ones2 - 1,
ones3 - 1, n))
# Assigning 1's to strings
# 3 & 1
if (ones3 > 0 and ones1 > 0 and
(n - i > ones2)):
option4 = (0 + maxXorValue(i + 1, s1,
s2, s3,
ones1 - 1,
ones2,
ones3 - 1, n))
# Assigning 1 to string 1
if (ones1 > 0 and (n - i > ones2)
and (n - i > ones3)):
option5 = ((1 << ((n - 1) - i))
+ maxXorValue(i + 1, s1,
s2, s3,
ones1 - 1,
ones2,
ones3, n))
# Assigning 1 to string 2
if (ones2 > 0 and (n - i > ones3) and
(n - i > ones1)):
option6 = ((1 << ((n - 1) - i)) +
maxXorValue(i + 1, s1,
s2, s3,
ones1,
ones2 - 1,
ones3, n))
# Assigning 1 to string 3.
if (ones3 > 0 and (n - i > ones2) and
(n - i > ones1)):
option7 = ((1 << ((n - 1) - i)) +
maxXorValue(i + 1, s1,
s2, s3,
ones1, ones2,
ones3 - 1, n))
# Assigning 0 to all the strings
if ((n - i > ones2) and (n - i > ones3) and
(n - i > ones1)):
option8 = (0 + maxXorValue(i + 1, s1,
s2, s3,
ones1,
ones2,
ones3, n))
# Take the maximum amongst all of
# the above solutions
dp[i][ones1][ones2][ones3] = max(option1,
max(option2,
max(option3,
max(option4,
max(option5,
max(option6,
max(option7,
option8)))))))
return dp[i][ones1][ones2][ones3]
# Function to get the count
# of ones in the string s
def onesCount(s):
count = 0
# Traverse the string
for x in s:
if (x == '1'):
count += 1
# Return the count
return count
# Utility Function to find
# the maximum XOR value after
# rearranging the digits
def maxXORUtil(s1, s2,
s3, n):
# Find the count of ones in
# each of the strings
ones1 = onesCount(s1)
ones2 = onesCount(s2)
ones3 = onesCount(s3)
global dp
# Function Call
print(maxXorValue(0, s1, s2, s3,
ones1, ones2,
ones3, n))
# Driver code
if __name__ == "__main__":
s1 = "11110"
s2 = "10101"
s3 = "00111"
n = len(s1)
# Function Call
maxXORUtil(s1, s2, s3, n)
# This code is contributed by Chitranayal
C#
// C# program for the
// above approach
using System;
class GFG{
// Dp table to store
// the sub-problems
static int[,,,] dp =
new int[20, 20,
20, 20];
// Function to find the
// maximum XOR value after
// rearranging the digits
static int maxXorValue(int i, String s1,
String s2, String s3,
int ones1, int ones2,
int ones3, int n)
{
// Base Case
if (i >= n)
return 0;
// Return if already calculated
if (dp[i, ones1,
ones2, ones3] != -1)
return dp[i, ones1,
ones2, ones3];
int option1 = 0, option2 = 0,
option3 = 0, option4 = 0,
option5 = 0, option6 = 0,
option7 = 0, option8 = 0;
// Assigning 1's to all
// string at position 'i'.
if (ones1 > 0 && ones2 > 0 &&
ones3 > 0)
// 2^(n-1-i) is the value
// added to the total
option1 = (1 << ((n - 1) - i)) +
maxXorValue(i + 1, s1,
s2, s3,
ones1 - 1,
ones2 - 1,
ones3 - 1, n);
// Assigning 1's to
// strings 1 & 2
if (ones1 > 0 && ones2 > 0 &&
(n - i > ones3))
option2 = 0 + maxXorValue(i + 1, s1, s2,
s3, ones1 - 1,
ones2 - 1,
ones3, n);
// Assigning 1's to strings 2 & 3
if (ones2 > 0 && ones3 > 0 &&
(n - i > ones1))
option3 = 0 + maxXorValue(i + 1, s1, s2,
s3, ones1,
ones2 - 1,
ones3 - 1, n);
// Assigning 1's to strings 3 & 1
if (ones3 > 0 && ones1 > 0 &&
(n - i > ones2))
option4 = 0 + maxXorValue(i + 1, s1, s2,
s3, ones1 - 1,
ones2,
ones3 - 1, n);
// Assigning 1 to string 1
if (ones1 > 0 && (n - i > ones2) &&
(n - i > ones3))
option5 = (1 << ((n - 1) - i)) +
maxXorValue(i + 1, s1,
s2,s3,
ones1 - 1,
ones2, ones3, n);
// Assigning 1 to string 2
if (ones2 > 0 && (n - i > ones3) &&
(n - i > ones1))
option6 = (1 << ((n - 1) - i)) +
maxXorValue(i + 1, s1,
s2, s3,
ones1,
ones2 - 1,
ones3, n);
// Assigning 1 to string 3.
if (ones3 > 0 && (n - i > ones2) &&
(n - i > ones1))
option7 = (1 << ((n - 1) - i)) +
maxXorValue(i + 1, s1,
s2, s3,
ones1,
ones2,
ones3 - 1, n);
// Assigning 0 to all the strings
if ((n - i > ones2) &&
(n - i > ones3) &&
(n - i > ones1))
option8 = 0 + maxXorValue(i + 1,
s1, s2,
s3, ones1,
ones2, ones3, n);
// Take the maximum amongst all of
// the above solutions
return dp[i, ones1,
ones2, ones3] = Math.Max(option1,
Math.Max(option2,
Math.Max(option3,
Math.Max(option4,
Math.Max(option5,
Math.Max(option6,
Math.Max(option7,
option8)))))));
}
// Function to get the count
// of ones in the string s
static int onesCount(String s)
{
int count = 0;
// Traverse the string
foreach(char x in s.ToCharArray())
{
if (x == '1')
++count;
}
// Return the count
return count;
}
// Utility Function to find the maximum
// XOR value after rearranging the digits
static void maxXORUtil(String s1, String s2,
String s3, int n)
{
// Find the count of ones in
// each of the strings
int ones1 = onesCount(s1);
int ones2 = onesCount(s2);
int ones3 = onesCount(s3);
// Initialize dp table with -1
for(int i = 0; i < 20; i++)
{
for(int j = 0; j < 20; j++)
{
for(int l = 0; l < 20; l++)
for(int k = 0; k < 20; k++)
dp[i, j, l, k] =- 1;
}
}
// Function Call
Console.WriteLine(maxXorValue(0, s1, s2, s3,
ones1, ones2,
ones3, n));
}
// Driver code
public static void Main(String[] args)
{
String s1 = "11110";
String s2 = "10101";
String s3 = "00111";
int n = s1.Length;
// Function call
maxXORUtil(s1, s2, s3, n);
}
}
// This code is contributed by 29AjayKumar
30
时间复杂度: O(N 4 )
辅助空间: O(N)