I've been assigned to do a problem that goes something like this:
My program should derive a list of integers A[1...N], where A[j] represents the jth integer in the list.
To derive it, my program will be inputted 5 lists, each of N integers (the same exact ones as in A[1...N], although scrambled). Each of these lists will be generated this way:
The list is put into order, just like A[1...N]. The list is then scrambled, which is done by removing at least 0 integers from this list, and placing them BACK into any position in the said list. In each of the 5 lists, each number is moved at most one time (although a number could end up at a different index as a result of other numbers shifting around).
FOR EXAMPLE
Assume N is 5, and the correct sequence A is {1, 2, 3, 4, 5}
The program would be entered these 5 sequences:
1,2,3,4,5
2,1,3,4,5
3,1,2,4,5
4,1,2,3,5
5,1,2,3,4
How would it be able to determine that the target/original sequence was {1,2,3,4,5}?
Could anyone point me in the right direction? (This is a homework problem)
Tell me if you need me to clarify the problem more.
Thanks!
I would create an array of size N and use it as an index for the other arrays. For instance, if you created an integer array index[N], you could manipulate it and use its values as indices for the other arrays, i.e. array1[index[N]]. Depending on how you manipulated this index array, you could use it for either scrambling or sorting.
Related
The problem is:
You have to sort an array in ascending order(permutation: numbers from 1 to N in a random order) using series of swaps. Every swap has a price and there are 5 types of prices. Write a program that sorts the given array for the smallest price.
There are two kinds of prices: priceByValue and priceByIndex. All of the prices of a kind are given in 2 two-dimensional arrays N*N. Example how to access prices:
You want to swap the 2nd and the 5th elements from the permutation with values of 4 and 7. The price for this swap will be priceByValue[4][7] + priceByIndex[2][5].
Indexes of all arrays are counted from 1 (, not from 0) in order to have access to all of the prices (the permutation elements’ values start from 1): priceByIndex[2][5] would actually be priceByIndex[1][4] in code. Moreover, the order of the indexes by which you access prices from the two-dimensional arrays doesn’t matter: priceByIndex[i][j] = priceByIndex[j][i] and priceByIndex[i][i] is always equal to 0. (priceByValue is the same)
Types of prices:
Price[i][j] = 0;
Price[i][j] = random number between 1 and 4*N;
Price[i][j] = |i-j|*6;
Price[i][j] = sqrt(|i-j|) *sqrt(N)*15/4;
Price[i][j] = max(i,j)*3;
When you access prices by index i and j are the indexes of the elements you want to swap from the original array; when you access prices by value i and j are the values of the elements you want to swap from the original array. (And they are always counted from 1)
Things given:
N - an integer from 1 to 400, Mixed array, Type of priceByIndex, priceByIndex matrix, Type of priceByValue, priceByValue matrix. (all elements of a matrix are from the given type)
Things that should 'appear on the screen': number of swaps, all swaps (only by index - 2 5 means that you have swapped 2nd and 3rd elements) and the price.
As I am still learning C++, I was wondering what is the most effective way to sort the array in order to try to find the sort with the smallest cost.
There might be a way how to access series of swaps that result a sorted array and see which one is with the smallest price and I need to sort the array by swapping the elements which are close by both value and index, but I don’t know how to do this. I would be very grateful if someone can give me a solution how to find the cheapest sort in code. Thank you in advance!
More: this problem might have no solution, I am just trying to get a result close to the ideal.
Dynamic Programming!
Think of the problem as a graph. Each of the N-factorial permutations represents a graph vertex, and the allowed swaps are just arcs between vertices. The price-tag of a swap is just the weight on the arc.
When you look at the problem this way, it can be easily solved with Dijkstra's algortihm for finding the lowest cost path through a graph from one vertex to another.
This is also called Single Pair Shortest Path
you can use an algorithm for sorting an array in lexicographical order and modify it so that it fits your needs ( you did not mention the sorting criteria like the desired result i.e. least value first, ... ) there are multiple algorithms available for this, i.e. quick sort,...
a code example is in https://www.geeksforgeeks.org/lexicographic-permutations-of-string/
I'd like to check if my vector / array is made of numbers.
I've tried:
if isa(x, Array{Number})
println("yes")
end
But it doesn't seem to work...
You have two scenarios here.
Scenario 1. You want to check if type of a vector allows only numbers. Then write:
eltype(x) <: Number
Scenario 2. You want to check if actually all elements of a vector are numbers. Then write:
all(isa.(x, Number))
The second is less efficient because it has to check the whole array. The reason why it might be sometimes needed is that you can have e.g.:
x = Any[1, 2, 3]
which contains only numbers, but type of the vector in general allows it to contain other things than numbers (so it will fail scenario 1 but pass scenario 2).
For the Longest Increasing Subsequence problem I envisioned keeping a DP array that is always in order keeping the max value at the farthest end. Something that would look like this:
{1, 1, 2, 3, 3, 4, 5, 6, 6, 6}
The thought process I followed to produce my first incorrect solution was, we want to look at the entire array starting with only the first element, calculate the LIS, then incrementally add on a value to the end of our array. While doing this, we incrementally calculate the LIS in our DP array to the LIS of the old subarray plus the new element we added on. This means at index i of the dp array exists the value of the LCS of the subarray of length i.
More clearly put
array => {5, 6, 7, 1, 2, 3, 4}
dp => {1, 2, 3, 3, 3, 3, 4}
This way the very last entry of the DP array will be the LIS of the current array. This would act as our invariant, so when we get the end, we can be assured that the last value is the only one we need. It then dawned on me that while we're traversing an array with a DP kinda feel, the next value does not depend on any of the previously tabulated values in the array, so this method is the same as maintaining a maxLIS variable, a pattern I've seen in many O(n) solutions. So my closest-to-correct solution is as follows:
1.) Save a copy of the input array/vector as old
2.) Sort the original input array
3.) Traverse the sorted array, incrementing a variable longest by one every time the next value (which should be larger than the current`) appears before the current in the original array.
4.) Return longest
The code would be ~this:
int lengthOfLIS(vector<int>& seq) {
if (!seq.size()) return 0;
vector<int> old = seq;
sort(seq.begin(), seq.end());
int longest = 1;
for (int i = 1; i < seq.size(); ++i) {
if (seq[i] > seq[i-1] && find(old.begin(), old.end(), seq[i]) - old.begin() > find(old.begin(), old.end(), seq[i-1]) - old.begin()) longest++;
}
return longest;
}
Where we have the find method (I'm assuming a linear operation) we could make a constant operation by just making a data structure to store the original index of the value along with the the value itself so we don't have to do any traversing to find the index of an element in the original array (old). I believe this would be an O(nlog(n)) solution however fails with this input array: [1,3,6,7,9,4,10,5,6]. CHECK HERE
Finally I did some research and I found that all solution guides I have read sneak in the fact that their solution keeps the values of their DP array not in order, but instead like this: A value in the DP array represents the length of an increasing subsequence with the last value of the subsequence being the value of originalArray[index].
More clearly put,
array => {5, 6, 7, 1, 2, 3}
dp => {1, 2, 3, 1, 2, 3}
Here, where 5 is the last value of an increasing subsequence, no values come before it so it must be of length 1. If 6 is the last value of an increasing subsequence, we must look at all values before it to determine how long a subsequence ending with 6 can be. Only 5 can come before it, thus making the longest increasing subsequence thus far 2. This continues, and you return the maximum value in the DP array. Time complexity for this solution is O(n^2), standard naive solution.
Questions:
I'm curious as to how I can think about this problem correctly. I want to fine-tune my thought process so that I can come up with an optimal solution from scratch (that's the goal at least) so I'd like to know
1.) What property of this problem should've triggered to me to use a DP array differently than how I would've used it? In hindsight, my original way was simply equivalent to keeping a max variable but even then I struggle seeing a property of this problem that would trigger the thought `Hey, the value of an entry in my DP array at index i should be the length of the increasing subsequence ending with originalArray[i]. I'm struggling to see how I should've come up with that.
2.) Is it possible to get my proposed O(nlog(n)) solution to work? I know an O(nlog(n)) solution exists, but since I can't get mine working I think I need a nudge in the right direction.
I admit, it is an interesting question and i do not have exact answer to it but i guess i can give you a nudge in right direction. So here it goes:
While facing with such dilemma, I would usually turn to the basics. Like in your case go through definition of Dynamic Programming. It has two properties:
Overlapping Subproblems
Optimal Substructure.
You can easily find these property reflecting in standard solution but not yours. You can read about them in cormen or just google them in context of DP.
In my opinion your solution is not a DP, you just found some pattern and your are trying to solve based on this pattern. If you are not getting the solution, it means that either your pattern is wrong or your solution is overlooking something. In scenarios like this try to prove, mathematically, that the pattern you are observing is correct and prove that the solution should also work.
Give me some more time, while i work through your solution but mean while you can also try to develop a proof for your solution.
I have thought of the following, but it requires a lot of memory.
Since I need to find the unique elements in any sub matrix and elements are within range 1-10, I create an array of size 10 for each matrix member, which stores the number of occurrences of each element up to that matrix member (from left) in that particular row.
e.g.
if row is 1, 2, 2, 4, 3, 5
then arr[3][10]={1,2,0,1,0,0,0,0,0,0} //for the 3rd element '4', '1' occurred once, '2' twice and '4' once.
and arr[5][10]={1,2,1,1,1,0,0,0,0,0} //for the last element '5'
Thus, I can find out the number of unique elements between any two members by just traversing each of the two arrays and see which of the array members are different.
I can push all the unique elements in each row of the sub matrix into a set and find the number of unique elements.
However, this method requires a lot of memory if the matrix size increases. Is there any better way to so this?
Sorry for the offtopic, but questions like this should result in ban.
You asked for a solution to problem from active programming contest:
http://www.codechef.com/DEC13/problems/RECTQUER
your approach is right. Go ahead and you will get AC. I implemented what you have written in your question and I got AC. use a 3-D matrix of size [300][300][10] and do exactly what you have suggested. Memory requirement will not be too high.
Given a integer array like
int numbers[8]={1, 3, 5, 7, 8, 6, 4, 2};
The half side in the front array are odd numbers, and the rest (the equal amount number)
are even. The odd numbers are in an ascending order and even part are in a descending order. After the sorting, the order of the numbers can't be changed.
How can I sort them alternatively with time complexity less than O(n^2) and space complexity O(1)?
For this example, the result would be: {1,8,3,6,5,4,7,2};
I can't use external array storage but temporary variables are acceptable.
I have tried to use two pointers(oddPtr, evenPtr) to point odd and even numbers separately, and move evenPtrto insert the even values to the middles of odd numbers.(Like insertion sort)
But it takes O(n^2).
UPDATED
As per Dukeling's comment I realized that the solution I propose in fact is not linear,but linearithmic and even worse - you can't control if it takes extra memory or not. On my second thought I realized you know a lot about the array you to implement a more specific, but probably easier solution.
I will make an assumption that all values in the array are positive. I need this so that I can use negative values as kind of 'already processed' flag. My idea is the following - iterate over the array from left to right. For each element if it is already processed(i.e. its value is negative) simply continue with the next one. Otherwise you will have a constant formula where is the position where this element should be:
If the value is odd and its index is i it should move to i*2
If the value is even and its index is i it should move to (i - n/2)*2 + 1
Store this value into a temporary and make the value at the current index of the array 0. Now until the position where the value we 'have at hand' is not zero, swap it with the value staying at the position we should place it according to the formula above. Also when you place the value at hand negate it to 'mark it as processed'. Now we have a new value 'at hand' and again we calculate where it should go according to the formula above. We continue moving values until the value we 'have at hand' should go to the position with 0. With a little thought you can prove that you will never have a negative('processed') value at hand and that eventually you will end up at the empty spot of the array.
After you process all the values iterate once over the array to negate all values and you will have the array you need. The complexity of the algorithm I describe is linear- each value will be no more than once 'at hand' and you will iterate over it no more than once.