Consider the following code:
public int find_exponent(array) {
int count = 0;
double min = epsilon;
for (int i=0; i<array.length; i++) {
if (array[i] < min) {
count++;
min = min/2;
}
}
return count;
}
Suppose the input array is of length n and randomly generated(and the entries are iid and ranges [0, 1]) from some unknown density f. What will be Expected Value of count ? I understand as the underlying density is unknown it's not possible to get an explicit solution but what I want is a solution in terms of f (or the corresponding CDF: F) and the initial guess for min i.e epsilon.
Note: I'm not interested to find the exact minimum in the given array
You can approach this problem the following way.
First off, I suppose that the type of min is meant to be float/double since your array array has values in the range [0, 1]. Now, define F as
F(x) = P(X <= x)
i.e the cumulative density function and G(i, c) to be the probability that after the i-th iteration we have that count == c
You can see that:
G(x, c) = P(X >= eps/2^c)*G(x, c) + P(X <= eps/2^(c-1))*G(x, c-1) =
(1-F(eps/2^c))*G(x, c) + F(eps/2^(c-1))*G(x, c-1)
Notice that since G(0, 0)=1 we can calculate G(x, c), for 0<=x<=n, 0<=c<=n with a bottom-up approach.
Here are the first couple of values of G:
G(0, 0) = 1
G(1, 0) = 1-F(e)
G(1, 1) = F(e)
G(2, 0) = (1-F(e))^2
G(2, 1) = F(e)(1-F(e)) + F(e)(1-F(e/2))
G(2, 2) = F(e)F(e/2)
The expected count would be:
E[count] = 0*G(n,0)+1*G(n,1)+...+n*G(n,n)
Related
Maximum Product.
The input to the problem is a string Z = z1,z2.....zn where each zi is any number between 1...9 and an integer k where 0 <= k < n.
An example string is Z = 8473817, which is of length n = 7. We want to insert k multiplication operators X into the string so that the mathematical result of the expression
is the largest possible. There are n - 1 possible locations for the operators,
namely, after the ith character where i = 1,....., n - 1.
For example, for input Z = 21322 and k = 2, then one possible way to insert the X operators
is: 2 X 1 X 322 = 644, another possibility is 21 X 3 X 22 = 1386.
Design a dynamic programming to output the maximum product
obtainable from inserting exactly k multiplication operators X into the string.
You can assume that all the multiplication operations in your algorithm take
O(1) time.
I am approaching this using the Matrix Chain Multiplication method where you compute smaller subproblem along the upper diagonal.
This works when K=1 i.e. one multiplication operator is inserted.
In the picture below, I have used 8473817 as an example and shown that 8473 X 817 yields the highest product.
How do I scale this solution for K > 1 and K < N.
Update: adding a pseudo code.
let A(i,j) store the max product for the strings A(i...j) 1 < i < j < n
for i = 1 -> n:
A(i,i) = Z(i)
for s = 1 -> n-1:
for i = 1 -> n-s:
j = i + s
A(i,j) = 0
for l = i -> j-1:
A(i,j) = max (A(i,j), A(i,l) * A(l+1,j)
return A(1,n)
The above code works when k = 1. How do I scale this up when k > 1 and less than n
Update
Based on #trincot solution, I revamped the soln to not use memoization
Sub problem Defn
Let T(i) store the start offset where inserting the X operator in Z yields max value for i : 1 < i < k.
Pseudo code
`
T(0) = 0
for i = 1 -> k:
max = 0
for j = T(i-1) + 1 -> n:
result = Z[1..j] * Z[j+1..n]
if result > max
max = result
T(i) = j
val = 1
for i = 1 -> k:
val = val * Z[T(i-1)+1...T(i)]
val = val * Z[T(k)+1..n]
Your pseudo code is a dynamic programming solution where you use memoization for every possible slice of z (2 dimensions, starting and ending offset). However, you would only need to memoize the best result for any suffix of z, so you would only need one (starting) offset. A second dimension in your memoization would then be used for the value of k (the number of remaining multiplications).
So you would still need a 2-dimensional table for memoization, but one index would be for k and the other for an offset in z.
Here is an implementation in JavaScript:
function solve(z, k) {
// Initialise a kxl array (where l is the length of z), filled with zeroes.
const memo = Array.from({length: k + 1}, () => Array(z.length + 1).fill(0));
function recur(z, k) {
if (k == 0) return z;
let result = memo[k][z.length];
if (result == 0) {
for (let i = 1; i <= z.length - k; i++) {
result = Math.max(result, +z.slice(0, i) * recur(z.slice(i), k - 1));
}
memo[k][z.length] = result;
}
return result;
}
return recur(z, k);
}
// A few example runs:
console.log(solve('8473817', 1)); // 6922441
console.log(solve('21322', 2)); // 1368
console.log(solve('191111', 2)); // 10101
Bottom up
The same can be done in an iterative algorithm -- bottom-up instead of top-down. Here we can save one dimension of the memoization array, as the same array can be re-used for the next value of k as it increases from 0 to its final value:
function solve(z, k) {
const memo = Array(z.length);
// Initialise for k=0:
// the best product in a suffix is the suffix itself
for (let i = 0; i < z.length; i++) {
memo[i] = +z.slice(i);
}
for (let kk = 1; kk <= k; kk++) {
for (let i = 0; i < z.length - kk; i++) {
// find best position for multiplication
let result = 0;
for (let j = i + 1; j < z.length - kk + 1; j++) {
result = Math.max(result, +z.slice(i, j) * memo[j]);
}
memo[i] = result;
}
}
return memo[0];
}
// A few example runs:
console.log(solve('8473817', 1)); // 6922441
console.log(solve('21322', 2)); // 1368
console.log(solve('191111', 2)); // 10101
(Code not supplied because this is homework.)
You have found that you can use the method once and get a solution for k=1.
Can you do it and find the best solution ending at every position in the string?
Now can you use the output of that second generalization and a similar method to get a complete solution for k=2?
Now can you write this a loop to solve for arbitrary k?
If you can do all that, then finishing is easy.
You have n-1 positions and k operators to insert. To me that looks like a binary number with n-1 bits including k 1's and the other positions set to 0.
Systematically generate all permutations of [0..01..1], insert multiplication operators at the 1 positions and calculate the result for each permutation.
How to efficiently generate all numbers within 0,1,2...n.
(large n).
Such that for a fixed x and varying k (0 <= k < n), k & x = k.
It is easily found out that all the bits with value 1 in k is also 1 in x.
But I have trouble computing all of them.
I used DP to find all the subset sums of set bit in x,to arrive at all the possible solutions.
But this method proves inefficient over multiple such cases requesting for a different x.
Do I have to consider each and every bit which needs to be changed to get all the possibilities?Any other efficient way? Also I certainly dont want to check with all of n.
There is a neat way to do that
for(int i = x ;; i = x & (i - 1)){
print i;
if(i == 0)
break;
}
Notice the condition i = x & (i - 1) make sure i always decreasing and only contains bits in x
See running Java code in here
In case x > n, so i should start with i = min(x, n - 1) & x
First note that the 0-bits in x denote the bits that must be 0 in k, while the 1-bits in x can be either 0 or 1 in k. The algorithm should thus iterate over all possible bit combinations in k for where x has a 1 bit and the resulting number (k) is not greater than n.
These combinations can best be produced by using something like a Grey code sequence, since one can then step from one bit pattern to the next in constant time.
Example:
x = 0b011010 (26)
n = 0b010000 (16)
The values to generate for k are (in order of Grey code sequence):
0b000000 ( = 0)
0b000010 ( = 2)
0b001010 ( = 10)
0b001000 ( = 8)
0b011000 ( = 24) too large: exclude
0b011010 ( = 26) too large: exclude
0b010010 ( = 18) too large: exclude
0b010000 ( = 16)
Because of using a Grey code scheme, only one bit changes from one combination to the next. This means that numbers are not generated in order and some can be too large (> n). This downside is worth it still, as generating them in order would involve more bit changes per step.
Here is a snippet that implements this idea in JavaScript:
function get_nums(n, x) {
// Solution array. Add zero as it is always a solution (assuming non-negative n)
let result = [0],
k = 0,
arr = []; // Helper to follow Grey code sequence
for (let i = 1; i <= n && i <= x; i <<= 1) { // Shift bit to the left
if (x & i) { // This bit is set to 1 in x
arr.push(i);
k += i; // Set this bit in k
if (k <= n) result.push(k); // Add k to solution array
// Produce other matches following Grey code sequence
for (let j = arr.length-2; j >= 0; j--) {
arr.push(-arr[j]);
k -= arr[j]; // Toggle a bit in k
if (k <= n) result.push(k);
}
}
}
return result;
}
console.log(get_nums(16, 26));
Note that the output is not ordered (because of the Grey code sequence used). If you need them ordered, apply some radix sort (or hashing).
In JavaScript it is quite easy to implement such a radix sort, given the values are unique. But in other languages you could implement a more explicit, simplified radix sort. Here is the JavaScript function for it:
function radix_sort_uniques(arr) {
let result = {};
// Add a property to the object for each value in the array
for (let i of arr) result[i] = true;
// Get those properties and convert them back to numeric data type (via map)
// JavaScript will produce them in ascending order:
return Object.keys(result).map(Number);
}
console.log(radix_sort_uniques([0, 2, 10, 8, 16]));
Complexity:
The outer loop iterates once per bit position in n, i.e. log(n) times, while the inner loop approximately doubles each time its number of iterations. So in the worst case (when x is 0 and the inner loop always executes) we get a total number of innermost operations in the order of 2log(n) times, giving a O(n) time complexity.
As x is fixed, the complexity should be expressed in x too. Let's say x has b 1-bits, then the time complexity is O(b+2b).
Imagine, that we have x in binary representation, like this:
x = 00001010110
In this case all k such that k & x = k should be in form
x = 00001010110
k = 0000?0?0??0
where ? is either 0 or 1. So we have to obtain all indexes 1 in x ([1, 2, 4, 6] in the example above) and generate all combinations (16 in the example) of 0 and 1s at the corresponding indexes:
C# implementation:
private static IEnumerable<int> MySolution(int x) {
int[] indexes = Enumerable
.Range(0, 32)
.Where(i => (x >> i) % 2 != 0)
.ToArray();
for (int value = 0; value < 1 << indexes.Length; ++value)
yield return indexes
.Select((v, i) => ((value >> i) % 2) * (1 << v))
.Sum();
}
Test:
Console.WriteLine(String.Join(", ", MySolution(5)));
Outcome (please, notice that the solutions are sorted out):
0, 1, 4, 5
If you want to restrict solutions generated, you can modify the loop:
private static IEnumerable<int> MySolution(int x, int n = -1) {
int[] indexes = Enumerable
.Range(0, 32)
.Where(i => (x >> i) % 2 != 0)
.ToArray();
for (int value = 0; value < 1 << indexes.Length; ++value) {
int result = indexes
.Select((v, i) => ((value >> i) % 2) * (1 << v))
.Sum();
if (n < 0 || result <= n)
yield return;
else
break;
}
}
Title says it all.
I need to split n as sum of k parts where each part ki should be in the range of
1 <= ki <= ri for given array r.
for example -
n = 4, k = 3 and r = [2, 2, 1]
ans = 2
#[2, 1, 1], [1, 2, 1]
Order matters. (2, 1, 1) and (1, 2, 1) are different.
I taught of solving it using stars and bars method, but be because of upper bound ri i dont know to to approach it.
i implemented a direct recursion function and it works fine for small values only.
Constraints of original problem are
1 <= n <= 107
1 <= k <= 105
1 <= ri <= 51
All calculations will be done under prime Modulo.
i found a similar problem here but i don't know how to implement in program. HERE
My brute-force recursive function -
#define MAX 1000
const int md = 1e9 + 7;
vector <int> k;
vector <map<int, int>> mapper;
vector <int> hold;
int solve(int sum, int cur){
if(cur == (k.size() - 1) && sum >= 1 && sum <= k[cur]) return 1;
if(cur == (k.size() - 1) && (sum < 1 || sum > k[cur])) return 0;
if(mapper[cur].find(sum) != mapper[cur].end())
return mapper[cur][sum];
int ans = 0;
int start = 1;
for(int i=start; i<=k[cur]; ++i){
int remain = sum - i;
int seg = (k.size() - cur) - 1;
if(remain < seg) break;
int res = solve(sum - i, cur + 1);
ans = (1LL * ans + res) % md;
}
mapper[cur][sum] = ans;
return ans;
}
int main(){
for(int i=0; i<MAX; ++i) k.push_back(51); // restriction for each part default 51
mapper.resize(MAX);
cout << solve(MAX + MAX, 0) << endl;
}
Instead of using a map for storing result of computation i used a two dimensional array and it gave very good performance boost but i cannot use it because of large n and k values.
How could i improve my recursive function or what are other ways of solving this problem.
That's interesting problem.
First lets say r_i = r_i - 1, n = n - k, numbers in [0, r_i] just for convenience. Now it's possible to add some fictitious numbers to make m the power of 2 without changing answer.
Now let's represent each interval of [0, r_i] as polynomial 1 * x ^ 0 + 1 * x ^ 1 + ... + 1 * x & r_i. Now if we multiply all these polynomials, coefficient at x ^ n will be answer.
Here is structure called Number Theoretic Transform (NTT) which allows to multiply two polynomials modulo p in O(size * log(size)).
If you will just multiply it using NTT, code will work in something like O(n * k * log (k * max(r))). It's very slow.
But now our fictive numbers help. Let's use divide and conquer technics. We'll make O(log m) steps, on each step multiply 2 * i-th and 2 * i + 1-th polynomials. In the next step we'll multiply resulting polynomials of this step.
Each step works in O(k * log(k)) and there is O(log(k)) steps, so algorhitm works in O(k * log^2 (k)). It's fast asymptotically, but I'm not sure if it fits TL for this problem. I think it will work about 20 seconds on max test.
You’re given an array of N 64 bit integers. N may be very large. You know that every integer 1..N appears once in the array, except there is one integer missing and one integer duplicated.
Write a linear time algorithm to find the missing and duplicated numbers. Further, your algorithm should run in small constant space and leave the array untouched.
Source: http://maxschireson.com/2011/04/23/want-a-job-working-on-mongodb-your-first-online-interview-is-in-this-post/
If all numbers were present in the array the sum would be N(N+1)/2.
Determine the actual sum by summing up all numbers in the array in O(n), let this be Sum(Actual).
One number is missing, let this be j and one number is duplicated, let this be k. That means that
Sum(Actual) = N(N+1)/2 + k - j
derived from that
k = Sum(Actual) -N(N+1)/2 + j
Also we can calculate the sum of squares in the array, which would sum up to
n3/3 + n2/2 + n/6 if all numbers were present.
Now we can calculate the actual sum of squares in O(n), let this be Sum(Actual Squares).
Sum(Actual Squares) =n3/3 +
n2/2 + n/6 + k2
- j2
Now we have two equations with which we can determine j and k.
The XOR trick works in two passes with a read-only array.
This avoids the problem of possible integer overflows which the sum and sum of squares solution has.
Let the two numbers be x and y, one of which is the missing number and the other repeated.
XOR all the elements of the array, along with 1,2,...,N.
The result is w = x XOR y.
Now since x and y are distinct, w is non-zero.
Pick any non-zero bit of w. x and y differ in this bit. Say the position of the bit is k.
Now consider a split of the array (and the numbers 1,2,...,N) into two sets, based on whether the bit at position k is 0 or 1.
Now if we compute the XOR (separately) of the elements of the two sets, the result has to be x and y.
Since the criteria for splitting is just checking if a bit is set of not, we can compute the two XORs of the two sets by making another pass through the array and having two variables, each of which holds the XOR of the elements seen so far (and 1,2,...N), for each set. At the end, when we are done, those two variables will hold x and y.
Related:
Finding missing elements in an array which can be generalized to m appearing twice and m missing.
Find three numbers appeared only once which is about three missing.
Using the basic idea from a related interview question you could do:
Sum up all the numbers (we shall call this S1) and their squares (S2)
Compute the expected sum of the numbers, without modifications, i.e. E1 = n*(n+1)/2 and E2 = n*(n+1)*(2n+1)/6
Now you know that E1 - S1 = d - m and E2 - S2 = d^2 - m^2, where d is the duplicated number and m the missing one.
Solve this system of equations and you'll find that:
m = 1/2 ((E2 - S2)/(E1 - S1) - (E1 - S1))
d = 1/2 ((E2 - S2)/(E1 - S1) + (E1 - S1)) // or even simpler: d = m + (E1 - S1)
.
$S1 = $S2 = 0;
foreach ($nums as $num) {
$S1 += $num;
$S2 += $num * $num;
}
$D1 = $n * ($n + 1) / 2 - $S1;
$D2 = $n * ($n + 1) * (2 * $n + 1) / 6 - $S2;
$m = 1/2 * ($D2/$D1 - $D1);
$d = 1/2 * ($D2/$D1 + $D1);
Here is a Java implementation based on #Aryabhatta 's idea:
Input:[3 1 2 5 3]
Output:[3, 4]
public ArrayList<Integer> repeatedNumber(final List<Integer> A) {
ArrayList<Integer> ret = new ArrayList<>();
int xor = 0, x = 0, y = 0;
for(int i=0; i<A.size(); i++) {
xor ^= A.get(i);
}
for(int i=1; i<=A.size(); i++) {
xor ^= i;
}
int setBit = xor & ~(xor-1);
for(int i=0; i<A.size(); i++) {
if((A.get(i) & setBit) != 0) {
x ^= A.get(i);
} else {
y ^= A.get(i);
}
}
for(int i=1; i<=A.size(); i++) {
if((i & setBit) != 0) {
x ^= i;
} else {
y ^= i;
}
}
for(int i=0; i<A.size(); i++) {
if(A.get(i) == x) {
ret.add(x);
ret.add(y);
return ret;
}
if(A.get(i) == y) {
ret.add(y);
ret.add(x);
return ret;
}
}
return ret;
}
The solution proposed by BrokenGlass covers the case for two unknowns (corresponding to one duplicate number and one missing number), using two formulas:
and
The formulas yield the generalized harmonic number of orders n of -1 and -2, respectively. (Power series)
This solution is generalizable for 3 unknowns by including the value of generalized harmonic number of order n of -3.
To solve for m unknowns (duplicates and missing numbers), use m generalized harmonic numbers of orders n of -1 through -m.
Moron notes that this approach was discussed earlier in StackOverflow at Easy interview question got harder.
Taking the leave the array untouched requirement literally (i.e. the array can be temporarily modified as long as it does not change in the end), a programming-oriented solution can be suggested.
I assume that array size N is much smaller than 2^64 which is an utterly unrealistic amount of memory. So we can safely assume that N < 2^P such that P << 64 (significantly smaller). In other words this means that all numbers in the array have some high bits unused. So let's just use the highest bit as a flag whether the index of that position has been seen in the array. The algorithm goes as follows:
set HIGH = 2^63 // a number with only the highest bit set
scan the array, for each number k do
if array[k] < HIGH: array[k] = array[k] + HIGH // set the highest bit
else: k is the duplicate
for each i in 1..N do
if array[i] < HIGH: i is missing
else: array[i] = array[i] - HIGH // restore the original number
This is linear time and very little computation
long long int len = A.size();
long long int sumOfN = (len * (len+1) ) /2, sumOfNsq = (len * (len +1) *(2*len +1) )/6;
long long int missingNumber1=0, missingNumber2=0;
for(int i=0;i<A.size(); i++){
sumOfN -= (long long int)A[i];
sumOfNsq -= (long long int)A[i]*(long long int)A[i];
}
missingno = (sumOfN + sumOfNsq/sumOfN)/2;
reaptingNO = missingNumber1 - sumOfN;
Psuedo code assuming the set is sorted
missing = nil
duplicate = nil
for i = 0, i < set.size - 1, i += 1
if set[i] == set[i + 1]
duplicate = set[i]
else if((set[i] + 1) != set[i+1])
missing = set[i] + 1
if missing != nil && duplicate != nil
break
return (missing, duplicate)
here is another dynamic programming question (Vazirani ch6)
Consider the following 3-PARTITION
problem. Given integers a1...an, we
want to determine whether it is
possible to partition of {1...n} into
three disjoint subsets I, J, K such
that
sum(I) = sum(J) = sum(K) = 1/3*sum(ALL)
For example, for input (1; 2; 3; 4; 4;
5; 8) the answer is yes, because there
is the partition (1; 8), (4; 5), (2;
3; 4). On the other hand, for input
(2; 2; 3; 5) the answer is no. Devise
and analyze a dynamic programming
algorithm for 3-PARTITION that runs in
time poly- nomial in n and (Sum a_i)
How can I solve this problem? I know 2-partition but still can't solve it
It's easy to generalize 2-sets solution for 3-sets case.
In original version, you create array of boolean sums where sums[i] tells whether sum i can be reached with numbers from the set, or not. Then, once array is created, you just see if sums[TOTAL/2] is true or not.
Since you said you know old version already, I'll describe only difference between them.
In 3-partition case, you keep array of boolean sums, where sums[i][j] tells whether first set can have sum i and second - sum j. Then, once array is created, you just see if sums[TOTAL/3][TOTAL/3] is true or not.
If original complexity is O(TOTAL*n), here it's O(TOTAL^2*n).
It may not be polynomial in the strictest sense of the word, but then original version isn't strictly polynomial too :)
I think by reduction it goes like this:
Reducing 2-partition to 3-partition:
Let S be the original set, and A be its total sum, then let S'=union({A/2},S).
Hence, perform a 3-partition on the set S' yields three sets X, Y, Z.
Among X, Y, Z, one of them must be {A/2}, say it's set Z, then X and Y is a 2-partition.
The witnesses of 3-partition on S' is the witnesses of 2-partition on S, thus 2-partition reduces to 3-partition.
If this problem is to be solvable; then sum(ALL)/3 must be an integer. Any solution must have SUM(J) + SUM(K) = SUM(I) + sum(ALL)/3. This represents a solution to the 2-partition problem over concat(ALL, {sum(ALL)/3}).
You say you have a 2-partition implementation: use it to solve that problem. Then (at least) one of the two partitions will contain the number sum(ALL)/3 - remove the number from that partion, and you've found I. For the other partition, run 2-partition again, to split J from K; after all, J and K must be equal in sum themselves.
Edit: This solution is probably incorrect - the 2-partition of the concatenated set will have several solutions (at least one for each of I, J, K) - however, if there are other solutions, then the "other side" may not consist of the union of two of I, J, K, and may not be splittable at all. You'll need to actually think, I fear :-).
Try 2: Iterate over the multiset, maintaining the following map: R(i,j,k) :: Boolean which represents the fact whether up to the current iteration the numbers permit division into three multisets that have sums i, j, k. I.e., for any R(i,j,k) and next number n in the next state R' it holds that R'(i+n,j,k) and R'(i,j+n,k) and R'(i,j,k+n). Note that the complexity (as per the excersize) depends on the magnitude of the input numbers; this is a pseudo-polynomialtime algorithm. Nikita's solution is conceptually similar but more efficient than this solution since it doesn't track the third set's sum: that's unnecessary since you can trivially compute it.
As I have answered in same another question like this, the C++ implementation would look something like this:
int partition3(vector<int> &A)
{
int sum = accumulate(A.begin(), A.end(), 0);
if (sum % 3 != 0)
{
return false;
}
int size = A.size();
vector<vector<int>> dp(sum + 1, vector<int>(sum + 1, 0));
dp[0][0] = true;
// process the numbers one by one
for (int i = 0; i < size; i++)
{
for (int j = sum; j >= 0; --j)
{
for (int k = sum; k >= 0; --k)
{
if (dp[j][k])
{
dp[j + A[i]][k] = true;
dp[j][k + A[i]] = true;
}
}
}
}
return dp[sum / 3][sum / 3];
}
Let's say you want to partition the set $X = {x_1, ..., x_n}$ in $k$ partitions.
Create a $ n \times k $ table. Assume the cost $M[i,j]$ be the maximum sum of $i$ elements in $j$ partitions. Just recursively use the following optimality criterion to fill it:
M[n,k] = min_{i\leq n} max ( M[i, k-1], \sum_{j=i+1}^{n} x_i )
Using these initial values for the table:
M[i,1] = \sum_{j=1}^{i} x_i and M[1,j] = x_j
The running time is $O(kn^2)$ (polynomial )
Create a three dimensional array, where size is count of elements, and part is equal to to sum of all elements divided by 3. So each cell of array[seq][sum1][sum2] tells can you create sum1 and sum2 using max seq elements from given array A[] or not. So compute all values of array, result will be in cell array[using all elements][sum of all element / 3][sum of all elements / 3], if you can create two sets without crossing equal to sum/3, there will be third set.
Logic of checking: exlude A[seq] element to third sum(not stored), check cell without element if it has same two sums; OR include to sum1 - if it is possible to get two sets without seq element, where sum1 is smaller by value of element seq A[seq], and sum2 isn't changed; OR include to sum2 check like previous.
int partition3(vector<int> &A)
{
int part=0;
for (int a : A)
part += a;
if (part%3)
return 0;
int size = A.size()+1;
part = part/3+1;
bool array[size][part][part];
//sequence from 0 integers inside to all inside
for(int seq=0; seq<size; seq++)
for(int sum1=0; sum1<part; sum1++)
for(int sum2=0;sum2<part; sum2++) {
bool curRes;
if (seq==0)
if (sum1 == 0 && sum2 == 0)
curRes = true;
else
curRes= false;
else {
int curInSeq = seq-1;
bool excludeFrom = array[seq-1][sum1][sum2];
bool includeToSum1 = (sum1>=A[curInSeq]
&& array[seq-1][sum1-A[curInSeq]][sum2]);
bool includeToSum2 = (sum2>=A[curInSeq]
&& array[seq-1][sum1][sum2-A[curInSeq]]);
curRes = excludeFrom || includeToSum1 || includeToSum2;
}
array[seq][sum1][sum2] = curRes;
}
int result = array[size-1][part-1][part-1];
return result;
}
Another example in C++ (based on the previous answers):
bool partition3(vector<int> const &A) {
int sum = 0;
for (int i = 0; i < A.size(); i++) {
sum += A[i];
}
if (sum % 3 != 0) {
return false;
}
vector<vector<vector<int>>> E(A.size() + 1, vector<vector<int>>(sum / 3 + 1, vector<int>(sum / 3 + 1, 0)));
for (int i = 1; i <= A.size(); i++) {
for (int j = 0; j <= sum / 3; j++) {
for (int k = 0; k <= sum / 3; k++) {
E[i][j][k] = E[i - 1][j][k];
if (A[i - 1] <= k) {
E[i][j][k] = max(E[i][j][k], E[i - 1][j][k - A[i - 1]] + A[i - 1]);
}
if (A[i - 1] <= j) {
E[i][j][k] = max(E[i][j][k], E[i - 1][j - A[i - 1]][k] + A[i - 1]);
}
}
}
}
return (E.back().back().back() / 2 == sum / 3);
}
You really want Korf's Complete Karmarkar-Karp algorithm (http://ac.els-cdn.com/S0004370298000861/1-s2.0-S0004370298000861-main.pdf, http://ijcai.org/papers09/Papers/IJCAI09-096.pdf). A generalization to three-partitioning is given. The algorithm is surprisingly fast given the complexity of the problem, but requires some implementation.
The essential idea of KK is to ensure that large blocks of similar size appear in different partitions. One groups pairs of blocks, which can then be treated as a smaller block of size equal to the difference in sizes that can be placed as normal: by doing this recursively, one ends up with small blocks that are easy to place. One then does a two-coloring of the block groups to ensure that the opposite placements are handled. The extension to 3-partition is a bit complicated. The Korf extension is to use depth-first search in KK order to find all possible solutions or to find a solution quickly.