Coin change,dynamic programming revisited - dynamic-programming

I am having tough time in understanding the logic behind this problem,
This is classical Dynamic Programming Problem
Coin Change is the problem of finding the number
of ways of making changes for a particular amount of cents, n,
using a given set of denominations d1,d2,..dm;
I know how the recursion works,Like taking the mth coin or not.But I don't understand what does '+' do between the two states.
For eg
C(N,m)=C(N,m-1)+C(N-dm,m)
^
|
Question might be stupid but I still would like to know so that I can have better understanding.Thanks

Well , you haven't written your state right!
Coin Change:
Let C(i,j) represents the number of ways to form j as a sum using only i coins (from i to 1).
Now to get a recursive function you have to define transitions or change in state or may be just expressing the given expression in the terms of lower values!!
There are 2 independent ways in which I can represent this state that are
1) Lets pick up the i th coin , Then what happens ? I need denomination j-Denomination[i] with i-1 coins if repetition is not allowed .
i.e. C(i,j)= C(i-1,j-Denominations[i])
But wait , we are missing some ways i.e. when we do not take the current coin
2) C(i,j)=C(i-1,j)
Now as both of them are independent and exhaustive , These both of these state makes up the total number of ways!!!
C(i,j)=C(i-1,j)+C(i-1,j-Denominations[i])
I will leave the recurrence when repetition allowed for you!

Related

Guess the number: Dynamic Programming -- Identifying Subproblems

I am working on the following problem and having a hell of a time at the moment.
We are playing the Guessing Game. The game will work as follows:
I pick a number between 1 and n.
You guess a number.
If you guess the right number, you win the game.
If you guess the wrong number, then I will tell you whether the number I picked is higher or lower, and you will continue guessing.
Every time you guess a wrong number x, you will pay x dollars. If you run out of money, you lose the game.
Given a particular n, return the minimum amount of money you need to guarantee a win regardless of what number I pick.
So, what do I know? Clearly this is a dynamic programming problem. I have two choices, break things up recursively or go ahead and do things bottom up. Bottom up seems like a better choice to me (though technically the max recursion depth would be 100 as we are guaranteed n<=100). The question then is: What do the sub-problems look like?
Well, I think we could start thinking about subarrays (but possible we need subsequences here) so what is the worst case in each possible sub-division kind of thing? That is:
[1,2,3,4,5,6]
[[1],[2],[3],[4],[5],[6]] -> 21
[[1,2],[3,4],[5,6]] -> 9
[[1,2,3],[4,5,6]] -> 7
...
but I don't think I quite have the idea yet. So, to get succinct since this post is kind of long: How are we breaking this up? What is the sub-problem we are trying to solve here?
Relevant Posts:
Binary Search Doesn't work in this case?

Reduce Time complexity

Question at hand : Complete the function minimumSwaps in the editor below. It must return an integer representing the minimum number of swaps to sort the array.
My Approach:
def minimumSwaps(arr):
count = 0
temp = [None]*len(arr)
res1=sorted(arr)
while(res1!=arr):
for i in range(int(len(arr))):
if(res1[i]!=arr[i]):
y=res1.index(arr[i])
arr[y] , arr[i]=arr[i] , arr[y]
count = count +1
return count
The code does give the required op for majority of the cases , but fails a few due to time limit exceeds error. Could someone suggest a few changes to reduce the time complexity issues and make the code more efficient. If Possible please try not to change the code in its entirety , I want to learn to make codes more efficient rather than trying a whole new approach altogether.
Link to one of the huge test case
To me, this is a graph problem. Maybe it's possible with a more simple solution, but I don't think so.
You can observe that to get the minimum swaps necessary, you'd just have to move every element into its sorted position. You can figure out where they're supposed to be by sorting and having an array indexed by element (or dictionary, for that matter) to the index.
Now, build a graph by making each item its own node, and connecting with a directed edge to the place it needs to be. We can observe that for a cycle of length k, we will need k-1 swaps to solve it. This is because we just need to swap each item forward, but the last swap actually solves two items rather than one. Thus, the answer is the sum of k-1 for each cycle, which can be reduced to n-c where c is the number of cycles.
To see why this works, consider the case of [2,3,1]. The sorted version of this array is [1,2,3]. Now, build the graph, where index 0 points to index 1 (since 2 needs to be in index 1), index 1 points to index 2, and index 2 points to index 0. We can run a search algorithm through the graph and find the number of cycles or components, and find that there is 1 cycle of length 3. So, the answer we produce is 3-1 = 2. As we can observe, this is indeed correct.
The problem gets a little more complicated if the array can contain duplicates, but it's not so bad, you'd just have to think a little harder. Maybe this isn't the intended solution, but it'll certainly work in O(n). Best of luck!

How to determine whether given language is regular or not(by just looking at the language)?

Is there any trick to guess if a language is regular by just looking at the language?
In order to choose proof methods, I have to have some hypothesis at first. Do you know any hints/patterns required to reduce time consumption in solving long questions?
For instance, in order not to spend time on pumping lemma, when language is regular and I don't want to construct DFA/grammar.
For example:
1. L={w ε {a,b}*/no of a in (w) < no of b in (w)}
2. L={a^nb^m/n,m>=0}
How to tell which is regular by just looking at the above examples??
In general, when looking at a language, a good rule of thumb for whether the language is regular or not is to think of a program that can read a string and answer the question "is this string in the language?"
To write such a program, do you need to store some arbitrary value in a variable or is the program's state (that is, the combination of all possible variables' values) limited to some finite fixed number of possibilities? If the language can be recognized by a program that only needs a fixed number of variables that can only have a fixed number of values, then you've got a regular language. If not, then not.
Using this, I can see that the first language is not regular, but the second language is. In the first language, I need to remember how many as I've seen, and how many bs. (Or at the very least, I need to keep track of (# of as) - (# of bs), and accept if the string ends while that count is negative). At the same time, there's no limit on the number of as, so this count could go arbitrarily large.
In the second language, I don't care what n and m are at all. So with the second language, my program would just keep track of "have I seen at least one b yet?" to make sure we don't have any a characters that occur after the first b. (So, one variable with only two values - true or false)
So one way to make language 1 into a regular language is to change it to be:
1. L={w ∈ {a,b}*/no of a in (w) < no of b in (w), and no of a in (w) < 100}
Now I don't need to keep track of the number of as that I've seen once I hit 100 (since then I know automatically that the string isn't in the language), and likewise with the number of bs - once I hit 100, I can stop counting because I know that'll be enough unless the number of as is itself too large.
One common case you should watch out for with this is when someone asks you about languages where "number of as is a multiple of 13" or "w ∈ {0,1}* and w is the binary representation of a multiple of 13". With these, it might seem like you need to keep track of the whole number to make the determination, but in fact you don't - in both cases, you only need to keep a variable that can count from 0 to 12. So watch out for "multiple of"-type languages. (And the related "is odd" or "is even" or "is 1 more than a multiple of 13")
Other mathematical properties though - for example, w ∈ {0,1}* and w is the binary representation of a perfect square - will result in non-regular languages.

Modelling Conway's game of life in integer linear programming?

I'm trying to model Conway's game of life rules using integer linear programming, however I'm stuck with one of the rules.
I consider a finite n x n grid. Each cell in the grid is associated with a variable X(i,j) whose value is 0 if the cell is dead and 1 if it is alive.
I'm particularly interested in still lifes, i.e. configurations that, according to the rules, don't change from an instant to the next.
To find them I'm imposing the constraints on the number of neighbours for each cell. So, for an alive cell to remain still it must have 2 or 3 neighbours, and this is easily expressible:
2(1-X(i,j)) + Σ(i,j) >= 2
-5(1 - X(i,j)) + Σ(i,j) <= 3
Where Σ(i, j) is the sum over the neighbours of (i, j) (assume outside of the grid the values are all 0s).
If X(i,j) == 0 then the first addend guarantees that the the constraints are trivially satisfied. When X(i, j) == 1 the constraints guarantee that we have a still life.
The problem is the other rule: for a dead cell to remain dead it must have any number of neighbours different from 3.
However, AFAIK you cannot use != in a constraint.
The closest I've come is:
X(i, j) + |Σ(i, j) - 3| > 0
Which does express what I want, but the problem is that I don't think the absolute value can be used in that way (only absolute values of single variables can be expressed. Or is there a way to express this particular situation?).
I wonder, is there a standard way to express the !=?
I was thinking that maybe I should use multiple inequalities instead of a single one (e.g. for every possible triple/quadruple of neighbours...), but I cannot think of any sensible way to achieve that.
Or maybe there is some way of abusing the optimization function to penalize this situation and thus, obtaining an optimum would yield a correct solution (or state that it's impossible, depending on the value).
Is anyone able to express that constraint using a linear inequality and the variables X(i, j) (plus, eventually, some new variables)?
The standard way to express
is to express it as
by introducing a new binary variable that indicates which inequality holds true.
This is explained here, at section 7.4.
In a nutshell, if we define y such that
then we need to add the constraints
Where
This is the standard way to model this, but in specific applications there might be better ways. Usually, the tighter the bounds on the sum are, the best the solver performance.

Dynamic Programming algorithm shortest path between two

There's an algorithm currently driving me crazy.
I've seen quite a few variations of it, so I'll just try to explain the easiest one I can think about.
Let's say I have a project P:
Project P is made up of 4 sub projects.
I can solve each of those 4 in two separate ways, and each of those modes has a specific cost and a specific time requirement:
For example (making it up):
P: 1 + 2 + 3 + 4 + .... n
A(T/C) Ta1/Ca1 Ta2/Ca2 etc
B(T/C) Tb1/Cb1 etc
Basically I have to find the combination that of those four modes which has the lowest cost. And that's kind of easy, the problem is: the combination has to be lower than specific given time.
In order to find the lowest combination I can easily write something like:
for i = 1 to n
aa[i] = min(aa[i-1],ba[i-1]) + value(a[i])
bb[i] = min(bb[i-1],ab[i-1]) + value(b[i])
ba[i] = min(bb[i-1],ab[i-1]) + value(b[i])
ab[i] = min(aa[i-1],ba[i-1]) + value(a[i])
Now something like is really easy and returns the correct value every time, the lowest at the last circle is gonna be the correct one.
Problem is: if min returns modality that takes the last time, in the end I'll have the fastest procedure no matter the cost.
If if min returns the lowest cost, I'll have the cheapest project no matter the amount of time taken to realize it.
However I need to take both into consideration: I can do it easily with a recursive function with O(2^n) but I can't seem to find a solution with dynamic programming.
Can anyone help me?
If there are really just four projects, you should go with the exponential-time solution. There are only 16 different cases, and the code will be short and easy to verify!
Anyway, the I'm pretty sure the problem you describe is the knapsack problem, which is NP-hard. So, there will be no exact solution that's sub-exponential unless P=NP. However, depending on what "n" actually is (is it 4 in your case? or the values of the time and cost?) there may be a pseudo-polynomial time solution. The Wikipedia article contains descriptions of these.

Resources