Optimal Movement in grid - algorithm

There is a maze of size N*M, consisting of unit blocks. At the start Alice has K percentage of energy.
Now Alice start from 1 st row and move towards N th row. From the present block she can move to a block in the next row, which is either on right or on left side of the present block. On moving to a block in i th row j th column, her energy will reduce by C(i,j) percent if C(i,j) is greater then 0, else it will be recharged by C(i,j) percent.
For Example if she has 50 percent of energy, on moving to block with C(i,j) = 15, she will have 35 ( 50 -15 ) percent of the it remaining.
Now the task is to find out the status of the Alice energy in the end, if she moves optimally to save maximum energy.
Note : Her energy will not exceed more than 100 percent, and she will not move further if her energy goes down to 0 percent .
EXAMPLE : Let us suppose a grid of 4*4 as follow :
2 -2 2 -2
-2 2 -2 2
1 -1 1 -1
-1 1 -1 1
And if K= 10 meaning she has 10 percent energy at start. then after reaching 4th row she will be having 16 percent energy.One of the optimal move will be <1,2> -> <2,1> -> <3,2> -> <4,1>
So here answer is 16.

I originally said you could solve this from the bottom up, but doing the example by hand I am going to work from the top down, because of the constraint that you cannot proceed once your energy goes down to zero - it doesn't come into play here, but it looks much easier to deal with if you are working from the top down. The principal is much the same - work row by row and at each stage write down the best score possible travelling through each cell, using the answers from the previous row to work out the answers for the current row.
We start out with 10, and I assume you can start out anywhere you want, so just subtract the top row from 10 to work out the best you can get to in the top row, including the energy difference from the cell you are now on. The top row becomes 8, 12, 8, 12.
The edge cells on the next row can only be reached in one way. The inner cells can be reached by two ways. In either case we work out the total there by taking account of the energy difference from that cell and the energy you could have from the cell you came from, taking the most promising choice when there are two. So we get 14, 10, 14, 10, where for example the second 14 is one of the 12ths above and to its left or above and two its right (if the scores were different we could take the best) combined with the -2 for that cell.
Similarly, we have 9, 15, 9, 15 for the next row and 16, 8, 16, 8 for the bottom, where for example the only way to get to the bottom left is from the 15 above and to its right, so adjusted by -1 we turn 15 into 16. There are two ways to get to the cell just to its right, but they both start from, 9, so adjusted by 1 we get 8.
If you need to whole path you can keep track of how you entered each cell as you work out the best cost to it, and then track your way up from the best answer when you are finished.

Related

How to perform range updates in sqrt{n} time?

I have an array and I have to perform query and updates on it.
For queries, I have to find frequency of a particular number in a range from l to r and for update, I have to add x from some range l to r.
How to perform this?
I thought of sqrt{n} optimization but I don't know how to perform range updates with this time complexity.
Edit - Since some people are asking for an example, here is one
Suppose the array is of size n = 8
and it is
1 3 3 4 5 1 2 3
And there are 3 queries to help everybody explain about what I am trying to say
Here they are
q 1 5 3 - This means that you have to find the frequency of 3 in range 1 to 5 which is 2 as 3 appears on 2nd and 3rd position.
second is update query and it goes like this - u 2 4 6 -> This means that you have to add 6 in the array from range 2 to 4. So the new array will become
1 9 9 10 5 1 2 3
And the last query is again the same as first one which will now return 0 as there is no 3 in the array from position 1 to 5 now.
I believe things must be more clear now. :)
I developed this algorithm long time (20+ years) ago for Arithmetic coder.
Both Update and Retrieve are performed in O(log(N)).
I named this algorithm "Method of Intervals". Let I show you the example.
Imagine, we have 8 intervals, with numbers 0-7:
+--0--+--1--+--2-+--3--+--4--+--5--+--6--+--7--+
Lets we create additional set of intervals, each spawns pair of original ones:
+----01-----+----23----+----45-----+----67-----+
Thereafter, we'll create the extra one layer of intervals, spawn pairs of 2nd:
+---------0123---------+---------4567----------+
And at last, we create single interval, covers all 8:
+------------------01234567--------------------+
As you see, in this structure, to retrieve right border of the interval [5], you needed just add together length of intervals [0123] + [45]. to retrieve left border of the interval [5], you needed sum of length the intervals [0123] + [4] (left border for 5 is right border for 4).
Of course, left border of the interval [0] is always = 0.
When you'll watch this proposed structure carefully, you will see, the odd elements in the each layers aren't needed. I say, you do not needed elements 1, 3, 5, 7, 23, 67, 4567, since these elements aren't used, during Retrieval or Update.
Lets we remove the odd elements and make following remuneration:
+--1--+--x--+--3-+--x--+--5--+--x--+--7--+--x--+
+-----2-----+-----x----+-----6-----+-----x-----+
+-----------4----------+-----------x-----------+
+----------------------8-----------------------+
As you see, with this remuneration, used the numbers [1-8]. Lets they will be array indexes. So, you see, there is used memory O(N).
To retrieve right border of the interval [7], you needed add length of the values with indexes 4,6,7. To update length of the interval [7], you needed add difference to all 3 of these values. As result, both Retrieval and Update are performed for Log(N) time.
Now is needed algorithm, how by the original interval number compute set of indexes in this data structure. For instance - how to convert:
1 -> 1
2 -> 2
3 -> 3,2
...
7 -> 7,6,4
This is easy, if we will see binary representation for these numbers:
1 -> 1
10 -> 10
11 -> 11,10
111 -> 111,110,100
As you see, in the each chain - next value is previous value, where rightmost "1" changed to "0". Using simple bit operation "x & (x - 1)", we can wtite a simple loop to iterate array indexes, related to the interval number:
int interval = 7;
do {
int index = interval;
do_something(index);
} while(interval &= interval - 1);

Maximum path cost in matrix

Can anyone tell the algorithm for finding the maximum path cost in a NxM matrix starting from top left corner and ending with bottom right corner with left ,right , down movement is allowed in a matrix and contains negative cost. A cell can be visited any number of times and after visiting a cell its cost is replaced with 0
Constraints
1 <= nxm <= 4x10^6
INPUT
4 5
1 2 3 -1 -2
-5 -8 -1 2 -150
1 2 3 -250 100
1 1 1 1 20
OUTPUT
37
Explanation is given in the image
Explanation of Output
Since you have also negative costs then use bellman-ford. What you do is that you change sign of all the costs(convert negative signs to positive and positive to negative) then find the shortest path and this path will be the longest because you have changed the signs.
If the sign is never becoms negative then use dijkstra shrtest-path but before that make all values negative and this will return you the longest path with it's cost.
You matrix is a direct graph. In your image you are trying to find a path(max or min) from index (0,0) to (n-1,n-1).
You need these things to represent it as a graph.
You need a linkedlist and in each node you have a first_Node, second_Node,Cost to move from first node to second.
An array of linkedlist. In each array index you save a linkedlist.If for example there is a path from 0 to 5 and 0 to 1(it's an undirected graph) then your graph will look like this.
If you want a direct-graph then simply add in adj[0] = 5 and do not add in adj[5] = 0 , this means that there is path from 0 to 5 but not from 5 to zero.
Here linkedlist represents only nodes which are connected not there cost. You have to add extra variable there which keep cost for each two nodes and it will look like this.
Now instead of first linkedlist put this linkedlist in your array and you have a graph now to run shortest or longest path algorithm.
If you want an intellgent algorithm then you can use A* with heuristic, i guess manhattan will be best.
If cost of your edges is not negative then use Dijkstra.
If cost is negative then use bellman-ford algorithm.
You can always find the longest path by converting the minus sign to plus and plus to minus and then run shortest path algorithm. Path founded will be longest.
I answered this question and as you said in comments to look at point two. If that's a task then main idea of this assignment is ensure the Monotonocity.
h stands for heuristic cost.
A stands for accumulated cost.
Which says that each node the h(A) =< h(A) + A(A,B). Means if you want to move from A to B then cost should not be decreasing(can you do something with your values such that this property will hold) but increasing and once you satisfy this condition then everyone node which A* chooses , that node will be part of your path from source to Goal because this is the path with shortest/longest value.
pathMax You can enforece monotonicity. If there is path from A to B such that f(S...AB) < f(S ..B) then set cost of the f(S...AB) = Max(f(S...AB) , f(S...A)) where S means source.
Since moving up is not allowed, paths always look like a set of horizontal intervals that share at least 1 position (for the down move). Answers can be characterized as, say
struct Answer {
int layer[N][2]; // layer[i][0] and [i][1] represent interval start&end
// with 0 <= layer[i][0] <= layer[i][1] < M
// layer[0][0] = 0, layer[N][1] = M-1
// and non-empty intersection of layers i and i+1
};
An alternative encoding is to note only layer widths and offsets to each other; but you would still have to make sure that the last layer includes the exit cell.
Assuming that you have a maxLayer routine that finds the highest-scoring interval in each layer (const O(M) per layer), and that all such such layers overlap, this would yield an O(N+M) optimal answer. However, it may be necessary to expand intervals to ensure that overlap occurs; and there may be multiple highest-scoring intervals in a given layer. At this point I would model the problem as a directed graph:
each layer has one node per score-maximizing horizontal continuous interval.
nodes from one layer are connected to nodes in the next layer according to the cost of expanding both intervals to achieve at least 1 overlap. If they already overlap, the cost is 0. Edge costs will always be zero or negative (otherwise, either source or target intervals could have scored higher by growing bigger). Add the (expanded) source-node interval value to the connection cost to get an "edge weight".
You can then run Dijkstra on this graph (negate edge weights so that the "longest path" is returned) to find the optimal path. Even better, since all paths pass once and only once through each layer, you only need to keep track of the best route to each node, and only need to build nodes and edges for the layer you are working on.
Implementation details ahead
to calculate maxLayer in O(M), use Kadane's Algorithm, modified to return all maximal intervals instead of only the first. Where the linked algorithm discards an interval and starts anew, you would instead keep a copy of that contender to use later.
given the sample input, the maximal intervals would look like this:
[0]
1 2 3 -1 -2 [1 2 3]
-5 -8 -1 2 -150 => [2]
1 2 3 -250 100 [1 2 3] [100]
1 1 1 1 20 [1 1 1 1 20]
[0]
given those intervals, they would yield the following graph:
(0)
| =>0
(+6)
\ -1=>5
\
(+2)
=>7/ \ -150=>-143
/ \
(+7) (+100)
=>12 \ / =>-43
\ /
(+24)
| =>37
(0)
when two edges incide on a single node (row 1 1 1 1 20), carry forward only the highest incoming value.
For each element in a row, find the maximum cost that can be obtained if we move horizontally across the row, given that we go through that element.
Eg. For the row
1 2 3 -1 -2
The maximum cost for each element obtained if we move horizontally given that we pass through that element will be
6 6 6 5 3
Explanation:
for element 3: we can move backwards horizontally touching 1 and 2. we will not move horizontally forward as the values -1 and -2, reduces the cost value.
So the maximum cost for 3 = 1 + 2 + 3 = 6
The maximum cost matrix for each of elements in a row if we move horizontally, for the input you have given in the description will be
6 6 6 5 3
-5 -7 1 2 -148
6 6 6 -144 100
24 24 24 24 24
Since we can move vertically from one row to the below row, update the maximum cost for each element as follows:
cost[i][j] = cost[i][j] + cost[i-1][j]
So the final cost matrix will be :
6 6 6 5 3
1 -1 7 7 -145
7 5 13 -137 -45
31 29 37 -113 -21
Maximum value in the last row of the above matrix will be give you the required output i.e 37

Networking Algorithm to Maximum a Subset of Integers

I'm currently working on a pet project that simulates a couple different types of networks. One of them requires some specific conditions that until now I've just been brute forcing. It's not scaling well, however, so I'm trying to do this efficiently but this algorithm is really stumping me! I'll try to describe the problem as general as possible.
Given a set of integers X and an integer k, find a subset Y of X that maximizes the sum of M over each value in X:
M(s) = the largest value in Y such that it is less than or equal to s.
For example, for {2, 4, 5} and k = 2 the solution is {2, 4} with value 2+4+4=10 since M(2) = 2, M(4) = 4, and M(5) = 5.
My intuition is that the solution is a dynamic programming algorithm, but I could be way off. Any help would be greatly appreciated!
Here is a dynamic program problem with a solution - I'm not sure if it's yours because I'm not sure of the details of what you have written, but it might be.
Sort the set of numbers and draw a curve with the x axis giving the offset of the number in sorted order and the y axis giving the number. There will be some area under the curve.
You have a finite number of points, usually a smaller number than there are members of the set. You can use each of these points to mark a point of the set, and so a point of the curve.
Draw a histogram under the curve. At each marked point there is a line from that point going right, so the lines are entirely under the curve. Each such line extends till it reaches the x value for the next marked point, at which point there is a line going up to the new marked point.
The challenge is then to select which points to mark to maximize the area under the horizontal lines going right from marked points. This is straightforward dynamic programming. If you can choose up to k marked points then at each point of the histogram work out the most area you can cover to the left of that point using 0, 1, 2, ..k marked points, possibly including that point. You can work out the answer for each point by referring to the answers you have already worked out for the points to its left. The answer for the rightmost point is the answer for the entire problem.
To expand this: Suppose you are working out the best solutions for maximum area ending at offset 10. For each value j of 0..k consider taking the previous best solution ending at 0, 1, 2, 3... 9 and maintaining the height at that point, without introducing a new line. The total area for this is the area up to that point plus the new area gained by whatever height they were in at that point times the distance back to that point. Also consider doing this, but using an extra marked point at that point, so the total area is the area of the best solution with j-1 points up to e.g. point 7 plus the distance back from point 10 to point 7 times the height reached at point 7. By considering these two possibilities you can work out the best solution at point 10 using 0,1,2,...k marked points.
I think these problems are related because for each point, marked or not, the area it contributes to the histogram depends on the height of the line above it, which is the height of the largest marked point no greater that the point we are considering at the moment.
To do this you need an array of kn elements giving the area covered by the best solution at each point using at most k marked points up to there. It will also be convenient to use an extra array of this size to record the decision that led to this best solution, so you can trace the answer back. This has a cost of about kn^2, because at each of n points you need to calculate k values, and look back at all the previous points as you do so. I suspect that you could reduce this to something like O(kn) by changing the definition of what you store at each point so you never have to look back further than one previous point. If you could do that, you could economize on store at the cost of time by only storing a few intermediate points and solving the problem over again on smaller sections to trace back, but you'ld need to be desperately short of store to make that worth while.
My answer is very similar than the other one:
The algorithm I suggest is to start having K=N, all numbers ordered, and keep removing numbers until you reach the desired K. The number you select to remove in each step, is the one who represent the lowest loss.
Example: Let's say you have the numbers:
3, 7, 9, 13 and 19
The problem is K=3
You start in K=5 (all numbers are selected).
3 + 7 + 9 + 13 + 19 = 51
First number to remove:
if 3 is selected:
0 + 7 + 9 + 13 + 19 = 48 (we lose 3)
if 4 is selected: (7 becomes 3)
3 + 3 + 9 + 13 + 19 = 47 (we lose 4)
if 9 is selected: (9 becomes 7)
3 + 7 + 7 + 13 + 19 = 49 (we lose 2)
if 13 is selected: we lose 13 - 9 = 4
if 19 is selected: we lose 19 - 13 = 6
Lowest loss in this case is: number 9 (loss=2).
We remove 9, and then we have K=4.
For the second number to remove, we have 4 options:
if we remove 3:
0 + 7 + 7 + 13 + 19 = # (we lose 3)
if we remove 7 all 7s will become 3s:
3 + 3 + 3 + 13 + 19 = # (we lose two 7s becoming 3 = (7-3) x 2 = 8)
if we remove 13:
3 + 7 + 7 + 7 + 19 (loss = 13 - 7 = 6)
if 19 is removed:
3 + 7 + 7 + 13 + 13 (loss = 6)
Best selection here is to remove #3
and then K=3 achieving the sum: 46
I don't know if this is optimal, you could verify by comparing vs. brute force multiple cases. But, even if this is not optimal, it can give good results.

Cycle sort Algorithm

I was browsing through the internet when i found out that there is an algorithm called cycle sort which makes the least number of memory writes.But i am not able to find the algorithm anywhere.How to detect whether a cycle is there or not in an array?
Can anybody give a complete explanation for this algorithm?
The cycle sort algorithm is motivated by something called a cycle decomposition. Cycle decompositions are best explained by example. Let's suppose that you have this array:
4 3 0 1 2
Let's imagine that we have this sequence in sorted order, as shown here:
0 1 2 3 4
How would we have to shuffle this sorted array to get to the shuffled version? Well, let's place them side-by-side:
0 1 2 3 4
4 3 0 1 2
Let's start from the beginning. Notice that the number 0 got swapped to the position initially held by 2. The number 2, in turn, got swapped to the position initially held by 4. Finally, 4 got swapped to the position initially held by 0. In other words, the elements 0, 2, and 4 all were cycled forward one position. That leaves behind the numbers 1 and 3. Notice that 1 swaps to where 3 is and 3 swaps to where 1 is. In other words, the elements 1 and 3 were cycled forward one position.
As a result of the above observations, we'd say that the sequence 4 3 0 1 2 has cycle decomposition (0 2 4)(1 3). Here, each group of terms in parentheses means "circularly cycle these elements forward." This means to cycle 0 to the spot where 2 is, 2 to the spot where 4 is, and 4 to the spot where 0 was, then to cycle 1 to the spot where 3 was and 3 to the spot where 1 is.
If you have the cycle decomposition for a particular array, you can get it back in sorted order making the fewest number of writes by just cycling everything backward one spot. The idea behind cycle sort is to try to determine what the cycle decomposition of the input array is, then to reverse it to put everything back in its place.
Part of the challenge of this is figuring out where everything initially belongs since a cycle decomposition assumes you know this. Typically, cycle sort works by going to each element and counting up how many elements are smaller than it. This is expensive - it contributes to the Θ(n2) runtime of the sorting algorithm - but doesn't require any writes.
here's a python implementation if anyone needs
def cycleSort(vector):
writes = 0
# Loop through the vector to find cycles to rotate.
for cycleStart, item in enumerate(vector):
# Find where to put the item.
pos = cycleStart
for item2 in vector[cycleStart + 1:]:
if item2 < item:
pos += 1
# If the item is already there, this is not a cycle.
if pos == cycleStart:
continue
# Otherwise, put the item there or right after any duplicates.
while item == vector[pos]:
pos += 1
vector[pos], item = item, vector[pos]
writes += 1
# Rotate the rest of the cycle.
while pos != cycleStart:
# Find where to put the item.
pos = cycleStart
for item2 in vector[cycleStart + 1:]:
if item2 < item:
pos += 1
# Put the item there or right after any duplicates.
while item == vector[pos]:
pos += 1
vector[pos], item = item, vector[pos]
writes += 1
return writes
x = [0, 1, 2, 2, 2, 2, 1, 9, 3.5, 5, 8, 4, 7, 0, 6]
w = cycleSort(x)
print w, x

How to display unique numbers with their frequencies as occurring in a matrix?

I have a matrice with some number:
1 2 3 6
6 7 2 1
1 4 5 6
And the program should display all different number with own frequency for example:
1 -> 3
2 -> 2
3 -> 1
4 -> 1
5 -> 1
6 -> 3
7 -> 1
Please help me
You probably mean
1->3
Create vector (array), filled with zeros, that have size of max value in matrice (like [0..9]), travell by whole matrice and with every step increment index of vector that equals actual number.
This is soluction for short range values in matrice. If you excpect some big values, use joined list insted of vector, or matrice like this for counting:
1 0
5 0
15 0
142 0
2412 0
And increment values in second column and expand this matrice rows every time you find a new number.
Using pointers this problem reduces from matrix to a single dimensional array. Maintain a 1D array whose size is equal to the total no. of elements in the matrix, say it COUNT. Initialize it with zero. Now start with first element of the matrix and compare it with all the other elements. If we use pointers this problem transforms into traversing a 1D array and finding the no of occurrences of each element. For traversing all you have to do is just increment the pointer. While comparing when you encounter the same number just shift forward all the consecutive numbers one place ahead. For example, if 0th element is 1 and you again found 1 on 4th index, then shift forward element on 5th index to 4th, 6th to 5th and so on till the last element. This way the duplicate entry at 4th index is lost. Now decrease the count of total no of elements in the matrix by 1 and increase the corresponding entry in array COUNT by 1. Continuing this way till the last element we get a matrix with distinct nos. and their corresponding frequency in array COUNT.
This implementation is very effective for languages which support pointers.
Here's an example of how it could be done in Python.
The dict is of this format: {key:value, key2:value2}. So you can use that so you have something like {'2':3} so it'll tell you what number has how many occurances. (I'm not assuming you're going to use Python. It's just so you understand the code... maybe)
matrix = [[1,5,6],
[2,6,3],
[5,3,9]]
dict = {}
for row in matrix:
for column in row:
if str(column) in dict.keys():
dict[str(column)] += 1
else:
dict[str(column)] = 1
for key in sorted(dict.keys()):
print key, '->', dict[key]
I hope you can figure out what this does. This codepad shows the output and nice syntax hightlighting.
(I don't get why SO isn't aligning the code properly... it's monospaced but not aligned :S ... turns out it's because I was using IE6 (It's the only browser at work :-(

Resources