Find the given sum "total" from the three matrixes algorithm - arrays

i was following the this question and i felt that this can be solved in O(NLogN). Below is my algorithm:
1. Sort list1 , list2, list3 i.e. O(NLogN)
2. while indexA < size and indexB < size and indexC < size //here size is the array size
int sum = a1[indexA] + a2[indexB] + a3[indexC]
if sum < total then choose the minimum value from a1, a2, a3 and increment that index
if sum > total print total can not be found and return
if sum == total then print the indexes
//this is O(N)
Hence all total O(NLogN).
Please tell me about the correctness of the above algo.
EDIT
As Muckle_ewe has explained that this algo will fail in some places so there is no point in further discussing on the algo rather please comment whether the question can be solvable in O(NLogN) if so then algo, thanks?

No that would fail on the
if sum < total then choose the minimum value from a1, a2, a3 and increment that index
line. Consider the following counter example (pseudocode)
list1 = [1, 10]
list2 = [2, 3]
list3 = [3, 4]
Let total be 7, for which the solution would be 1 + 2 + 4 (or 1 + 3 + 3). Let indexA = indexB = indexC = 0. Initial sum is then
list1[0] + list2[0] + list3[0]
1 + 2 + 3 = 6
As this is less than 7, we increase the index which gave the smallest list value, which was indexA as list1[indexA] = 1. Sum is then
list1[1] + list2[0] + list3[0]
10 + 2 + 3 = 15
As this is greater than 7 your algorithm tells us there is no solution

Related

Maximize sum of array after applying the given operations on the array

Given an Array A consisting of N elements and an integer K. You can perform following operations on array any number of times(Can be 0).
Choose an element from array A. Let us denote as A[i]
Choose a positive integer Y.
Change A[i] to A[i] xor Y.
The Sum of all the Y's used in the operations should not be greater than K.
Your task is to find the maximum sum of all the elements of array A after operations.
Example:-
N=5
K=6
A={9,7,7,4,3}
Output:- 36
Explanation:- In the first operation, choose the fourth element and Y=2. Then change 4 to 4 xor 2, that is 6.
the updated array will be:- 9,7,7,6,3
In second Operation, choose the fifth element and Y=4. Then change 3 to 3 xor 4, that is 7.
The updated array will be 9,7,7,6,7
Hence sum is 36.
Please someone explain the logic behind the problem. I am not getting the idea.
Since you didn't clarify my comment about Y I will assume that the answer is no, you can not count unique Y values once towards the budget K.
This problem is simply a modified 0-1 knapsack problem in disguise. To solve it using the knapsack problem:
Let the item value & weight pairs be defined as the set
I = { (Y ^ a - a, Y) : a \in A, Y \in {1,K}}
Apply the dynamic programming solution to the 0-1 knapsack problem with weight limit K, and the requirement that only one item may be picked per a \in A. The total optimal weight of the knapsack problem + any unmodified a \in A is the solution.
Here is an implementation in python that solves the example given.
#!/usr/bin/python
def solve2(w,v,W,nK):
n = len(w)
m = dict()
for j in range(0,W+1):
m[-1, j] = 0
for i in range(-1,n):
m[i, 0] = 0
for i in range(0,n):
for j in range(0,W+1):
b_w = -1
b_v = -1
found = False
for k in range(0,nK):
if w[i][k] <= j and v[i][k] >= b_v:
b_w = w[i][k]
b_v = v[i][k]
found = True
if found:
m[i, j] = max(m[i-1, j], m[i-1, j-b_w] + b_v)
else:
m[i, j] = m[i-1, j]
return m[n-1,W]
A = [9,7,7,4,3]
K = 6
v = [ [ (Y^a)-a for Y in range(1,K+1) ] for a in A]
w = [ [ Y for Y in range(1,K+1) ] for a in A]
print ('Solution value is:', sum(A) + solve2(w,v,K,K))

Count maximum inversions for k subarrays

I have this problem:
Given an array A and an integer K, partition A into K contiguous subarrays in the way that maximizes the sum of the number of inversions in each subarray. (An "inversion" is a pair of indices i, j where i < j and A[i] > A[j].)
Return the sum.
For example, if A = 9 1 7 2 3 and K = 2, then the answer is 4, because you can split the array into 9 1 7 2 (which has four inversions) and 3 (which has none), and 4 + 0 = 4.
Constaints
1 <= A.size <= 500
1 <= k <= A.size
1 <= A[i] <= 100000
My thoughts:
This looks like a dynamic programming problem but I can't work out how to integrate K groups into the solution.
This problems roughly translates to finding K groups with each group having the highest number of increasing elements within that group.
Any ideas on how to solve this would be helpful.
We can at least have an O(n^2 * k) dynamic program. Let f(i, k) represent the most inversions up to index i with k groups. Then:
f(i, k) = max(
inversion_count(j, i) + f(j - 1, k - 1)
)
for k <= j <= i
We can precalculate a step to make the result for inversion_count(interval) O(1) time by using O(n^2) time and space: for all elements, e, in A, store how many smaller elements are in each interval that starts at e. When we decrease j in the main iteration, increasing the size of the interval, the number of inversions increases by the number of elements smaller than A[j] in the interval [j, i], which we've precalculated.

Counting appropriate number of subarrays in an array excluding some specific pairs?

Let's say, I have an array like this:
1 2 3 4 5
And given pair is (2,3), then number of possible subarrays that don't have (2,3) present in them will be,,
1. 1
2. 2
3. 3
4. 4
5. 5
6. 1 2
7. 3 4
8. 4 5
9. 3 4 5
So, the answer will be 9.
Obviously, there can be more of such pairs.
Now, one method that I thought of is of O(n^2) which involves finding all such elements of maximum length n. Can I do better? Thanks!
Let's see, this adhoc pseudocode should be O(n):
array = [1 2 3 4 5]
pair = [2 3]
length = array.length
n = 0
start = 0
while (start < length)
{
# Find next pair
pair_pos = start
while (pair_pos < length) and (array[pair_pos,pair_pos+1] != pair) # (**1)
{
pair_pos++
}
# Count subarrays
n += calc_number_of_subarrays(pair_pos-start) # (**2)
# Continue after the pair
start = pair_pos+2
}
print n
Note **1: This seems to involve a loop inside the outer loop. Since every element of the array is visited exactly once, both loops together are O(n). In fact, it is probably easy to refactor this to use only one while loop.
Note **2: Given an array of length l, there are l+(l-1)+(l-2)+...+1 subarrays (including the array itself). Which is easy to calculate in O(1), there is no loop involved. c/f Euler. :)
You don't need to find which subarrays are in an array to know how many of them there are. Finding where the pair is in the array is at most 2(n-1) array operations. Then you only need to do a simple calculation with the two lengths you extract from that. The amount of subarrays in an array of length 3 is, for example, 3 + 2 + 1 = 6 = (n(n+1))/2.
The solution uses that in a given array [a, ..., p1, p2, ..., b], the amount of subarrays without the pair is the amount of subarrays for [a, ..., p1] + the amount of subarrays for [p2, ..., b]. If multiple of such pairs exist, we repeat the same trick on [p2, ..., b] as if it was the whole array.
function amount_of_subarrays ::
index := 1
amount := 0
lastmatch := 0
while length( array ) > index do
if array[index] == pair[1] then
if array[index+1] == pair[2] then
length2 := index - lastmatch
amount := amount + ((length2 * (length2 + 1)) / 2)
lastmatch := index
fi
fi
index := index + 1
od
//index is now equal to the length
length2 := index - lastmatch
amount := amount + ((length2 * (length2 + 1)) / 2)
return amount
For an array [1, 2, 3, 4, 5] with pair [2, 3], index will be 2 when the two if-statements are true. amount will be updated to 3 and lastmatch will be updated to 2. No more matches will be found, so lastmatch is 2 and index is 5. amount will be 3 + 6 = 9.

Sum of all subparts of an array of integers

Given an array {1,3,5,7}, its subparts are defined as {1357,135,137,157,357,13,15,17,35,37,57,1,3,5,7}.
I have to find the sum of all these numbers in the new array. In this case sum comes out to be 2333.
Please help me find a solution in O(n). My O(n^2) solution times out.
link to the problem is here or here.
My current attempt( at finding a pattern) is
for(I=0 to len) //len is length of the array
{
for(j=0 to len-i)
{
sum+= arr[I]*pow(10,j)*((len-i) C i)*pow(2,i)
}
}
In words - len-i C i = (number of integers to right) C weight. (combinations {from permutation and combination})
2^i = 2 power (number of integers to left)
Thanks
You can easily solve this problem with a simple recursive.
def F(arr):
if len(arr) == 1:
return (arr[0], 1)
else:
r = F(arr[:-1])
return (11 * r[0] + (r[1] + 1) * arr[-1], 2 * r[1] + 1)
So, how does it work? It is simple. Let say we want to compute the sum of all subpart of {1,3,5,7}. Let assume that we know the number of combinatiton of {1,3,5} and the sum of subpart of {1,3,5} and we can easily compute the {1,3,5,7} using the following formula:
SUM_SUBPART({1,3,5,7}) = 11 * SUM_SUBPART({1,3,5}) + NUMBER_COMBINATION({1,3,5}) * 7 + 7
This formula can easily be derived by observing. Let say we have all combination of {1,3,5}
A = [135, 13, 15, 35, 1, 3, 5]
We can easily create a list of {1,3,5,7} by
A = [135, 13, 15, 35, 1, 3, 5] +
[135 * 10 + 7,
13 * 10 + 7,
15 * 10 + 7,
35 * 10 + 7,
1 * 10 + 7,
3 * 10 + 7,
5 * 10 + 7] + [7]
Well, you could look at at the subparts as sums of numbers:
1357 = 1000*1 + 100*3 + 10*5 + 1*7
135 = 100*1 + 10*3 + 1*5
137 = 100*1 + 10*3 + 1*7
etc..
So, all you need to do is sum up the numbers you have, and then according to the number of items work out what is the multiplier:
Two numbers [x, y]:
[x, y, 10x+y, 10y+x]
=> your multiplier is 1 + 10 + 1 = 12
Three numbers [x, y, z]:
[x, y, z,
10x+y, 10x+z,
10y+x, 10y+z,
10z+x, 10z+y,
100x+10y+z, 100x10z+y
.
. ]
=> you multiplier is 1+10+10+1+1+100+100+10+10+1+1=245
You can easily work out the equation for n numbers....
If you expand invisal's recursive solution you get this explicit formula:
subpart sum = sum for k=0 to N-1: 11^(N-k) * 2^k * a[k]
This suggests the following O(n) algorithm:
multiplier = 1
for k from 0 to N-1:
a[k] = a[k]*multiplier
multiplier = multiplier*2
multiplier = 1
sum = 0
for k from N-1 to 0:
sum = sum + a[k]*multiplier
multiplier = multiplier*11
Multiplication and addition should be done modulo M of course.

Increment values in an array with constraints using Matlab?

Scenario :
If I have an array with 4 loads (a1 a2 a3 a4)
a=[a1 a2 a3 a4] (locations of these loads must be fixed)
a=[1 2 3 3]
I would like to try and increase all values in the array to 3.
Note : the array a is not fixed, and can have any value from 0:3
Constraints :
There is a priority array that cannot be violated
Number of total increments is limited to 3
Given :
Priority array v=[1 3 2 1] -- (1 is highest priority, and 3 is lowest priority).
Note : the array v is not fixed, and can have any value from 0:3
Using this priority array :
a(1,1)=highest priority
a(1,4)=2nd highest priority
a(1,3)=3rd priority
a(1,2)=lowest priority
Implementation, my trial in pseudo code :
a=[1 2 3 3]
v=[1 3 2 1]
count=3
Check highest priority : a(1,1)
increment by 1
decrement count by 1
count = 2
still less than 3 ? if yes, then increment again until a(1,1)<= 3 AND count >=0
Change highest priority to 5 (so that min(v) will not pick it up)
ans : a=[3 2 3 3] ; v=[5 2 3 3] ; count = 1
Check highest priority : a(1,3)
value >= 3
Change highest priority to 5 (so that min(v) will not pick it up)
skip
ans : a=[3 2 3 3] ; v=[5 2 5 3] ; count = 1
Check highest priority : a(1,4)
value >=3
Change highest priority to 5 (so that min(v) will not pick it up)
skip
ans : a=[3 2 3 3] ; v=[5 2 5 5] ; count = 1
Check highest priority : a(1,2)
increment by 1
decrement count by 1
count = 0
still less than 3 ? if yes, then increment again until a(1,1)<= 3 AND count >=0
Change highest priority to 5 (so that min(v) will not pick it up)
ans = [a1 a2 a3 a4] = [3 3 3 3]
Note : if a priority value = [1 1 1 1] is reached, then a is prioritised from left to right (I haven't found a better way to do this)
I hope this makes sense, and that my pseudo code shows what I'm trying to implement. Ask me if something is not clear.
You could do something like this
a = [1 2 3 3];
v = [1 3 2 1];
% Sort a in the order of priority v
[vSrt, indSrt] = sort(v);
a = a(indSrt);
nIncsRemaining = 3; % Total no. of increments allowed
target = 3; % Target value for each value in a
for curInd = 1:length(a)
% Difference from target
aDiff = target - a(curInd);
% Do we need to increment this value of a?
if aDiff > 0
% Increment by a maximum of nIncsRemaining
aDelta = min(aDiff, nIncsRemaining);
% Increment a and decrement no. of increments remaining by the
% same amount
a(curInd) = a(curInd) + aDelta;
nIncsRemaining = nIncsRemaining - aDelta;
end
% Have we done as much as we're allowed?
if nIncsRemaining == 0, break; end
end
The key step is the sorting of the priority array, and the sorting of a by the same indices. Then you can just loop through a, being confident that you're beginning with the highest priority.
If you require the same order as the input at output, then you can invert the sorting operation by doing
[~, indReSrt] = sort(indSrt);
a = a(indReSrt);
The array v was not modified in the first place, so you don't need to invert the sort on that array.
Here's what I came up with:
a = [1 2 3 3];
v = [1 3 2 1];
% Get priority vector - this converts v into the indices of a that are most important in descending order. This can also be preallocated for speed or stored in place if v is not important;
priority_vec = [];
for i = 0:3
% Get indices
priority_vec = horzcat(priority_vec,find(v == i));
end
% Loop over priority_vec
count = 3; % count is the number of additions you can make
for i = 1:4 % Loop over the indices of priority vec
priority_ind = priority_vec(i); % This is the current index of most importance
while(a(priority_ind) < 3 && count ~= 0) % Continue to add one while count is greater than 0 and the value at the priority index is less than three
a(priority_ind) = a(priority_ind) + 1;
count = count - 1;
end
end
Another version:
a = [1 2 3 3];
v = [1 3 2 1];
count = 3;
target = 3;
Sort a and v in priority order
[vSorted, order] = sort(v);
aSorted = a(order);
Find position that will cause count to equal 0
pos = find(cumsum(target - aSorted) >= count);
Update all values up until but not including pos, decrement count accordingly
count = count - sum(3 - aSorted(1:pos - 1));
vSorted(1:pos - 1) = 5;
aSorted(1:pos - 1) = target;
Update the value s at pos
aSorted(pos) = aSorted(pos) + count;
count = 0;
if aSorted(pos) == target
vSorted(pos) = 5;
end
Restore sort order
[~, invOrder] = sort(order);
a = aSorted(invOrder);
v = vSorted(invOrder);
If v is only used to determine the priority there is no need to update it.
If count may still be non-zero after all values of a have reached target some extra handling of that case is required as that will cause pos = find(...); to return an empty array.

Resources