给定三个长度为N 的二进制字符串S1 、 S2和S3 ,任务是找到通过重新排列给定字符串的字符可以获得的最大可能的按位异或。
例子:
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设置位。为获得最大 Bitwise 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的合适重新排列,以便使用动态规划最大化它们的按位异或值。子问题可以存储在dp[][][][]表中,其中dp[i][o1][o2][o3]存储从索引i开始直到位置N-1的最大异或值,其中o1是 , o2和o3分别是仍要放置在字符串S1 、 S2和S3 中的1的数量。
在从0到(N – 1) 的任何位置i可能有四种情况:
- 将1 s 分配给所有三个字符串
- 将1 s 分配给任意两个字符串
- 将1 s 分配给任何一个字符串。
- 将0分配给所有字符串。
从上述每个位置的可能情况,计算从四种可能性中可获得的最大按位异或:
请按照以下步骤解决问题:
- 初始化一个表dp[][][][]来存储S1 、 S2和S3中位置i从0 到 N-1 的数量。
- 过渡状态如下:
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)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live