给定大小为N的数组和整数K。任务是将数组划分为K个分段,以使各个分段和的按位与最大。找到可以得到的按位与的最大值。
例子:
Input : a[] = { 2, 5, 6, 9, 1, 3, 10, 12 }, K = 3
Output : 8
Explanation :
Maximum bitwise AND can be obtained by making cut at 3rd element and 5th element(1 based indexing)
(2+5+6)&(9+1)&(3+10+12) = 8
Input : a[] = { 1, 2, 7, 10, 23, 21, 6, 8, 7, 3 } , K = 2
Output : 41
Explanation:
Maximum bitwise AND can be obtained by making cut at 5th element(1 based indexing)
(1+2+7+10+23)&(21+6+8+7+3) = 41
方法:
首先,尝试回答一个更简单的问题:给定一个整数x并确定是否有可能将给定数组划分为K个段,以使段之和按位与具有x的所有置位位?
让我们通过第i个段表示元素之和 。此外,我们姑且称之为段好,如果具有x的所有置位位。现在很清楚的是有一个良好的段我,AND( , x )= x 。
同样,所有的K段都应该很好地获得x的按位与。现在检查是否可以将数组划分为k个良好的段。我们可以在这里使用动态编程。
令dp [i] [j] = true ,表示可以将第一个i元素划分为j个段,以便所有j个都是好段,否则为false 。
dp以上的重复发生次数为:
dp[i][j] is 1, if for some index k
从贪婪的答案的最高有效位开始构建dp表。
下面是上述方法的实现:
C++
// CPP program to find maximum possible AND
#include
using namespace std;
// Function to check whether a k segment partition
// is possible such that bitwise AND is 'mask'
bool checkpossible(int mask, int* arr, int* prefix, int n,
int k)
{
// dp[i][j] stores whether it is possible to partition
// first i elements into j segments such that all j
// segments are 'good'
bool dp[n + 1][k + 1];
// Initialising dp
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
// Filling dp in bottom-up manner
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= k; j++) {
// Finding a cut such that first l elements
// can be partitioned into j-1 'good' segments
// and arr[l+1]+...+arr[i] is a 'good' segment
for (int l = i - 1; l >= 0; --l) {
if (dp[l][j - 1] && (((prefix[i] - prefix[l])
& mask) == mask)) {
dp[i][j] = 1;
break;
}
}
}
}
return dp[n][k];
}
// Function to find maximum possible AND
int Partition(int arr[], int n, int k)
{
// Array to store prfix sums
int prefix[n+1];
for (int i = 1; i <= n; i++) {
prefix[i] = prefix[i - 1] + arr[i];
}
// Maximum no of bits in the possible answer
int LOGS = 20;
// This will store the final answer
int ans = 0;
// Constructing answer greedily selecting
// from the higher most bit
for (int i = LOGS; i >= 0; --i) {
// Checking if array can be partitioned
// such that the bitwise AND is ans|(1<
Java
// Java program to find maximum possible AND
class GFG
{
// Function to check whether a k segment partition
// is possible such that bitwise AND is 'mask'
static boolean checkpossible(int mask, int arr[],
int prefix[], int n, int k)
{
int i,j;
// dp[i][j] stores whether it is possible to partition
// first i elements into j segments such that all j
// segments are 'good'
boolean dp[][] = new boolean[n + 1][k + 1];
// Initialising dp
for(i = 0; i < n + 1; i++)
{
for(j = 0; j < k + 1; j++)
{
dp[i][j] = false ;
}
}
dp[0][0] = true;
// Filling dp in bottom-up manner
for ( i = 1; i <= n; i++)
{
for (j = 1; j <= k; j++)
{
// Finding a cut such that first l elements
// can be partitioned into j-1 'good' segments
// and arr[l+1]+...+arr[i] is a 'good' segment
for (int l = i - 1; l >= 0; --l)
{
if (dp[l][j - 1] && (((prefix[i] - prefix[l])
& mask) == mask))
{
dp[i][j] = true;
break;
}
}
}
}
return dp[n][k];
}
// Function to find maximum possible AND
static int Partition(int arr[], int n, int k)
{
// Array to store prfix sums
int prefix[] = new int[n+1];
for (int i = 1; i <= n; i++)
{
prefix[i] = prefix[i - 1] + arr[i];
}
// Maximum no of bits in the possible answer
int LOGS = 20;
// This will store the final answer
int ans = 0;
// Constructing answer greedily selecting
// from the higher most bit
for (int i = LOGS; i >= 0; --i)
{
// Checking if array can be partitioned
// such that the bitwise AND is ans|(1<
Python3
# Python3 program to find maximum possible AND
# Function to check whether a k segment partition
# is possible such that bitwise AND is 'mask'
def checkpossible(mask,arr,prefix, n,k):
# dp[i][j] stores whether it is possible to partition
# first i elements into j segments such that all j
# segments are 'good'
dp=[[0 for i in range(k+1)] for i in range(n + 1)]
# Initialising dp
dp[0][0] = 1
# Filling dp in bottom-up manner
for i in range(1, n+1):
for j in range(1, k+1):
# Finding a cut such that first l elements
# can be partitioned into j-1 'good' segments
# and arr[l+1]+...+arr[i] is a 'good' segment
for l in range(i-1,-1,-1):
if (dp[l][j - 1] and (((prefix[i] - prefix[l]) & mask) == mask)):
dp[i][j] = 1
break
return dp[n][k]
# Function to find maximum possible AND
def Partition(arr, n, k):
# Array to store prfix sums
prefix=[0 for i in range(n+1)]
for i in range(1,n+1):
prefix[i] = prefix[i - 1] + arr[i]
# Maximum no of bits in the possible answer
LOGS = 20
# This will store the final answer
ans = 0
# Constructing answer greedily selecting
# from the higher most bit
for i in range(LOGS,-1,-1):
# Checking if array can be partitioned
# such that the bitwise AND is ans|(1<
C#
// C# program to find maximum possible AND
using System;
class GFG
{
// Function to check whether a
// k-segment partition is possible
// such that bitwise AND is 'mask'
static Boolean checkpossible(int mask, int []arr,
int []prefix,
int n, int k)
{
int i, j;
// dp[i,j] stores whether it is possible
// to partition first i elements into
// j-segments such that all j-segments are 'good'
Boolean[,] dp = new Boolean[n + 1, k + 1];
// Initialising dp
for(i = 0; i < n + 1; i++)
{
for(j = 0; j < k + 1; j++)
{
dp[i, j] = false;
}
}
dp[0, 0] = true;
// Filling dp in bottom-up manner
for ( i = 1; i <= n; i++)
{
for (j = 1; j <= k; j++)
{
// Finding a cut such that first l elements
// can be partitioned into j-1 'good' segments
// and arr[l+1]+...+arr[i] is a 'good' segment
for (int l = i - 1; l >= 0; --l)
{
if (dp[l, j - 1] &&
(((prefix[i] - prefix[l]) &
mask) == mask))
{
dp[i, j] = true;
break;
}
}
}
}
return dp[n, k];
}
// Function to find maximum possible AND
static int Partition(int []arr, int n, int k)
{
// Array to store prfix sums
int []prefix = new int[n + 1];
for (int i = 1; i <= n; i++)
{
prefix[i] = prefix[i - 1] + arr[i];
}
// Maximum no of bits in the possible answer
int LOGS = 20;
// This will store the final answer
int ans = 0;
// Constructing answer greedily selecting
// from the higher most bit
for (int i = LOGS; i >= 0; --i)
{
// Checking if array can be partitioned
// such that the bitwise AND is ans|(1<
41
时间复杂度: O( klog(S)),其中S = + +…。+ 。