How to define subproblem in Dynamic Programming? - algorithm

I solved several dynamic programming problems but i don't know how to come up with defining a subproblem. For problem max sum even length subarray, why they define dp[i] = the maximum sum of an even length subarray starting at i.
Do you have any tips or theorem about that?
thanks in advance.

I don't think there is any theorem about it. It is simply, a matter of training. You should continue doing examples and it will come.

Related

Subset sum with unlimited elements

I am trying to solve a coding problem at topcoder for practice. I believe I have solved it partly, but am struggling with the other half.
The essence of the problem is "Given a set P with positive integers, find the smallest set of numbers that adds up to a sum S. You can use an element of the set more than once. There may be a case where the sum is not attainable as well."
For small inputs, the exponential algorithm of searching through all possible subsets works. However, the size of the set can go up to 1024.
What is the idea behind solving this problem? Is this problem even an extension of subset-sum?
[EDIT]
This is the problem on topcoder : https://community.topcoder.com/stat?c=problem_statement&pm=8571

Come up with polynomial algorithm

Given n checks, each of arbitrary (integer) monetary value, decide if the checks can be partitioned into two parts that have the same monetary value.
I'm beyond mind blown on how to solve this. Is there an algorithm to solve this in polynomial time or is this NP-Complete?
Yes it's an NP complete problem. It's a variation of the subset sum problem.
Actually you can solve this in O(n*sum/2) using dynamic programming, first sum up all checks into a varaibel sum, then you can perform dp on the checks values (either take it or leave it or take it) and check at the end if that sum is equal to s/2.

Bin Packing regarding Optimization and Decision Versions

I'm studying for an exam and we were given a set of practice problems. Here's one I'm struggling with and I hope somebody can help shed some light on the right approach to this problem:
Here's my initial go at the problem:
Decision Version:
To find the optimal solution using the decision version, I would try using various K's until I got a yes answer. Let's say the optimized solution is 7, I would try :
k=1, no
k=2, no
k=3, no
k=4, no
k=5, no
k=6, no
k=7, yes.
So now that we know that the optimal solution is 7 bins, we solve the decision version by sorting the items by sizes from largest to smallest, and filling up the bins filling largest to smallest, and looping back over the bins until they are no more elements in the set.
If we have an optimal solution and we want to solve the decision version, I would take the number of bins returned by the optimal solution, and run it on the decision version to see if it returns yes.
I've never really seen a problem like this before so I'm not sure how the proper format is supposed to be.
Any help would be greatly appreciated!
There is a much better approach to solving the optimization problem based on the decision problem, note that your solution is exponential (pseudo-polynomial, but still exponential) in the size of the input, since if you have an algorithm that runs in T(n) on the decision problem, the suggested solution runs in O(k*T(n)), but since k is actually exponential in the size of the input (you need only log(k) bits to represent it), you have an exponential run time.
However, you can apply binary search on the problem, and require only O(log(k)) invokations of the algorithm of the decision problem in order to solve the optimization problem.
Now, if P=NP, and such algorithm (for solving the decision problem) exists in polynomial time O(p(n)), solving the optimization problem will be done in O(p(n) * log(k)) - which is polynomial in the size of the input.
The binary search will go something like that:
k <- 1
while decision_bin_packing(G,k) == false:
k <- k * 2
perform binary search for the smallest value t in [k/2,k] such that decision_bin_packing(G,t)==true
The last binary search is pretty standard, and can be easily implemented with only O(logk) invokations of decision_bin_packing.

How to find proper formula for a dynamic programming algorithm

I reading about Dynamic Programming. I read that to be able to get good at it, needs practice and intuition but this advice seems to general to me.
The hardest part for me is to figure out a recursive formula. Sometimes the formula used in the solution does not seem that intuitive to me.
For example I read the problem following problem:
You have 2 strings S and T. Give an algorithm to find the number of
times S appears in T. It is not mandatory for all characters of S to
appear contiguous in T.
The solutions is based on the following recurrence formula, which for me is not intuitive at all:
Assume M(i, j) represents the count of how many times i characters of
S appear in j characters of T. Base cases:
i) 0 if j = 0
ii) 1 if i = 0
I was wondering is there some kind of "analysis" of the problem that helps define/find the proper recurrence formula for a solving a problem via DP?
It's described very well on the Wikipedia, here:
"In mathematics, computer science, and economics, dynamic programming is a method for solving complex problems by breaking them down into simpler sub-problems. It is applicable to problems exhibiting the properties of overlapping sub-problems and optimal substructure (described below). When applicable, the method takes far less time than naive methods."
Read also about overlapping sub-problems and optimal substructure.
Maybe this link gets useful:
https://www.geeksforgeeks.org/solve-dynamic-programming-problem/
https://www.geeksforgeeks.org/tabulation-vs-memoization/
1. How to classify a problem as a Dynamic Programming Problem?
2. Deciding the state
3. Formulating a relation among the states
4. Adding memoization or tabulation for the state

Recurrence Equations

Given a problem, how to come up with a recurrence equation?
For example :
Let S be a set of n>0 distinct integers. Assume that n is a power of 3.
A ternary comparison can compare three numbers from the set S and
order them from the largest to the smallest.
Describe an efficient algorithm that uses as few as possible ternary comparisons to find the largest number in the set S.
This is one of the midterm question I had. I come up with
T(n) = 3T(n/3)+1
and other students come up with something else.
In general what to look for while finding a recursion for a problem?
It depends on the problem, but in general try to split the problem up into a smaller problem plus one more step, or several smaller problems, and a step that combines them.
I think your answer is right. How did you get to the answer? Can you explain the process you followed?
Here's how I would do it:
You can split the problem by partitioning the integers into three smaller, equally sized groups. Assume you know how to find the maximum of each smaller group in T(n/3), and then using your ternary comparison operator to find the maximum of the three maximums in one extra step (giving the +1). This is then the overall maximum. This gives the recurrence relationship you described. You also need to define the base case: T(1) = 0 or T(3) = 1. This doesn't prove that it is optimal, but I think you can prove that it is using a different argument.
Most recursive solutions follow similar patterns but there is no hard and fast rule you can always follow. Just practice on many different examples until you get the hang of it.

Resources