here is another dynamic programming problem that find the maximum L(chess horse - 4 item) sum in the given matrix (m x n)
For example :
1 2 3
4 5 6
7 8 9
L : (1,2,3,6), (1,4,5,6), (1,2,5,8), (4,5,6,9) ...
and the biggest sum is sum(L) = sum(7,8,9,6) = 30
what is the O(complexity) of the optimal solution ?
it looks like this problem (submatrix with maximum sum)
Say all items are positive
Both positive and negative
Any ideas are welcome!
If your L is constant size (4 elements, as you say), just compute its sum over all < n*m positions and find the maximum one. Repeat for the 8 different orientations you could have. That's O(nm) overall.
Related
Given an m x n matrix and an integer k. Where k is the area of the rectangle inside the matrix. Now we want to minimize the sum of the elements of this rectangle.
What is the idea of this problem? Can it be solved with dynamic programming?
for example :
1 2 3
4 5 6
7 8 9
k=4
ans = 12
I have M intervals on the real line, each with a positive weight. I need to select N among them such that they don't overlap and give the maximum sum. How can I do that efficiently ?
If there is no subset of N non-overlapping intervals, there is no solution.
Without the non-overlap constraint, the question is trivial: pick the N largest weights. Because of the constraint, this doesn't work anymore. In my case, N and M are small (<20), but I hope that there is a more efficient solution than exhaustively trying all subsets.
You can solve it with dynamic programming. Let C(k, i) be the maximum sum of (up to) k weighted intervals, none of which has their left end less than i.
You can restrict i to be in the set of (real) start points for all the intervals, and k ranges from 0 to N.
Start by initializing C(k, max(start for start, end in interval)) to 0, and all other entries to -infinity.
Sort the intervals by start points, and iterate through them backwards.
For each interval (start, end) with weight w, and for each k:
C(start, k) = max(C(start, k), C(next(start), k), w + C(next'(end), k-1))
Here next(x) returns the smallest start point greater than x, and next'(x) returns the smallest start point greater than or equal to x. Both can be implemented by binary search (or linear scan if M is small).
Overall, this is going to take O(M*N*logM) time and O(M*N) space.
(This assumes the intervals aren't closed at both ends, so (0, 100) and (100, 200) don't overlap -- a small adjustment needs to be made if these are to be considered overlapping).
In progress:
Inspired by #PaulHankin's solution, here is a reformulation.
Sort all intervals by increasing right abscissa and iteratively find the largest possible sum up to the K-th right bound. Assume you have solved all optimization problems for the first K intervals and for all relevant N (from 0 to K).
When you take the next interval into consideration, you compute new candidate solutions as follows: for every N (up to the current nomber of intervals), lengthen all previous solutions that you can (including the empty one) without causing overlap, and keep the lenghtened solutions that are better.
Example:
The optimal sums up to the K-th right bound, by increasing N are
1: 2
2: 2 or 8 => 8 | -
3: 8 or 3 => 8 | 2 + 3 | -
4: 8 or 2 => 8 | 2 + 3 or 8 + 2 => 8 + 2 | 2 + 3 + 2 | -
5: 8 or 9 => 9 | 8 + 2 or 2 + 9 => 2 + 9 | 2 + 3 + 2 | - | -
Say I have an array of N numbers {A1, A2, ... , An} and 2 numbers P, Q
I have to find an integer M between P and Q , such that, min {|Ai-M|, 1 ≤ i ≤ N} is maximised.
1 < N < P ≤ Q ≤ 10^6
in simpler words:
for each number, find the minimum absolute difference between this number and the array.
then out of all those minimum differences, find the number who has the highest minimum difference.
I have to do this in O(NlogN) or less.
I have tried the following:
sort the array A (NlogN)
iterate over all the numbers between P and Q and for each number find the minimum difference using modified binary search and keep track who has the highest difference - O((Q-P)logN)
I'm guessing there is some kind of math "trick" like using average I'm missing..
edit (add example):
for example if you have the array
{5 8 14}
and P=4 Q=9
the answer is 4,6,7, or 9.
lets look at the numbers 4-9
|4-5| = 1
|4-8| = 4
|4-14| = 10
so minimum diff for 4 is 1
|5-5| = 0
|5-8| = 3
|5-14| = 9
so minimum diff for 4 is 0
we keep going and find minimum diff for all the numbers and then we need to say which number (4/5/6/7/8/9) had the highest minimum diff (in this example 4,6,7 and 9 have 1 minimum difference which is max among all minimum differences)
First you have to sort an array. Then you have to notice that your solution is either P or Q or some point x[i] = (A[i] + A[i+1]) // 2. Basically x[i] is in the middle between consecutive elements in the array (if this x[i] is between P, Q).
Because N is really small, this will run basically in O(1).
This question already has answers here:
Take K elements and maximise the minimum distance
(2 answers)
Closed 7 years ago.
We are given N elements in form of array A , Now we have to choose K indexes from N given indexes such that for any 2 indexes i and j minimum value of |A[i]-A[j]| is as large as possible. We need to tell this maximum value.
Lets take an example : Let N=5 and K=2 and array be [1,5,3,7,11] then here answer is 10 as we can simply choose first and last position and differ = 11-1=10.
Example 2 : Let N=10 and K=3 and array A be [3 9 6 11 15 20 23] then here answer will be 8. As we can select [3,11,23] or [3,15,23].
Now given N , K and Array A we need to find this maximum difference.
We are given that 1 ≤ N ≤ 10^5 and 1 ≤ S ≤ 10^7
Let's sort the array.
Now we can do a binary search over the answer.
For a fixed candidate x, we can just pick the elements greedily(iterating over the sorted array and taking each element if we can). If the number of elements we have picked is not less than K, x is feasible. Otherwise, it is not.
The time complexity is O(N * log N + N * log (MAX_ELEMENT - MIN_ELEMENT))
A pseudo code:
bool isFeasible(int x):
cnt = 1
last = a[0]
for i <- 1 ... n - 1:
if a[i] - last >= x:
last = a[i]
cnt++
return cnt >= k
sort(a)
low = 0
high = a[n - 1] - a[0] + 1
while high - low > 1:
mid = low + (high - low) / 2
if isFeasible(mid):
low = mid
else
high = mid
print(low)
I think this can be dealt with as a dynamic programming problem. Start off by sorting A, and then the problem is to mark K elements in A such that the minimum difference between adjacent marked items is as large as possible. As a starter, you can always mark the first and last elements.
Moving from left to right, at each position for i=1..N work out the largest minimum difference you can get by marking i elements in the sub-array terminating at this position. You can work out the largest minimum difference for k items terminating at this position by considering the largest minimum difference for k-1 items terminating at each position to the left of the position you are working on. The obvious thing to do is to consider each possible position up to the position you are currently working on as ending a stretch of k-1 items with minimum difference, but you may be able to do a binary search here to speed things up.
Once you have worked all the way to the right hand end you know the maximum possible value for the original problem. If you need to know where to put the K elements, you can take notes as you go along so that you can backtrack to find out the elements chosen that lead to this solution, working from right to left.
From http://discuss.joelonsoftware.com/default.asp?interview.11.794054.1
The sequence A is defined as follows:
Start with the natural numbers
1,2,3,...
Initialize count = 1;
while(there are uncrossed numbers)
{
pick the first uncrossed number say n.
set A[count] = n.
Cross out the number count+n.
Cross out the number n
Increment count.
}
Give a fast algorithm to determine A[n], given n.
Try getting an algorithm which is polynomial in log n.
Sorry for posting this question.
Apparently this is a famous sequence called Wythoff's sequence and there is a neat formula for A[n] given by A[n] = [n*phi] where [x] = integral part of x and phi is the golden ratio.
To calculate [nphi], we can approximate phi as a ratio of consecutive fibonacci numbers, giving an O(lognloglogn) algorithm. (O(logn) time to do arithmetic on O(log n) bit numbers).
Here is how it starts
1 2 3 4 5 6 7 8 ... A[1] = 1, cross 2
1 X 3 4 5 6 7 8 ... A[2] = 1, cross 3
1 X X 4 5 6 7 8 ... A[3] = 1, cross 4
...
number 1 is never crossed because the least number that can be crossed is 1+1==2.
So there is constant time algorithm: A[n] = 1 for all n.