Showing posts with label Dynamic Programing. Show all posts
Showing posts with label Dynamic Programing. Show all posts

Wednesday, October 12, 2016

Assembly Line Scheduling

A car factory has two assembly lines, each with n stations. A station is denoted by Si,j where i is either 1 or 2 and indicates the assembly line the station is on, and j indicates the number of the station. The time taken per station is denoted by ai,j. Each station is dedicated to some sort of work like engine fitting, body fitting, painting and so on. So, a car chassis must pass through each of the n stations in order before exiting the factory. The parallel stations of the two assembly lines perform the same task. After it passes through station Si,j, it will continue to station Si,j+1 unless it decides to transfer to the other line. Continuing on the same line incurs no extra cost, but transferring from line i at station j – 1 to station j on the other line takes time ti,j. Each assembly line takes an entry time ei and exit time xi which may be different for the two lines. Give an algorithm for computing the minimum time it will take to build a car chassis.

http://www.geeksforgeeks.org/dynamic-programming-set-34-assembly-line-scheduling/


Sunday, August 7, 2016

Given an integer matrix, find the length of the longest increasing path

From each cell, you can either move to four directions: left, right, up or down. You may NOT move diagonally or move outside of the boundary (i.e. wrap-around is not allowed).
Example 1:
nums = [
  [9,9,4],
  [6,6,8],
  [2,1,1]
]
Return 4
The longest increasing path is [1, 2, 6, 9].
Strategy: Dynamic Programming
This is a very classic DFS + memorialization problem. If we only use the DFS solution, it will end with many repeated calculations. Therefore, for each element in the matrix[i][j], we use a DP array dp[i][j] to denote the length of the maximum increasing path from this point. So along with the DFS, for a point in the matrix, if we've already found the longest increasing path, we don't have to repeatedly compute it again; we just need to return the length, which is dp[i][j].

One trick here is dp[i][j] stores the length of the longest increasing path. That is because the DFS from a point matrix[i][j] can guarantee the longest path from this point. Since we store this value in the dp[i][j], that can guarantee that dp[i][j] is the longest path from the point matrix[i][j].

http://www.geeksforgeeks.org/find-the-longest-path-in-a-matrix-with-given-constraints/
http://buttercola.blogspot.in/2016/06/leetcode-329-longest-increasing-path-in.html
http://adijo.github.io/2016/01/20/leetcode-longest-increasing-path-matrix/


Wednesday, July 27, 2016

Highway Billboard Problem

Sup­pose you’re man­ag­ing con­struc­tion of bill­boards on the Rocky & Bull­win­kle Memo­r­ial High­way, a heav­ily trav­eled stretch of road that runs west-east for M miles. The pos­si­ble sites for bill­boards are given by num­bers x1 < x2 < · · · < xn, each in the inter­val [0, M], spec­i­fy­ing their posi­tion in miles mea­sured from the west­ern end of the road. If you place a bill­board at posi­tion xi , you receive a rev­enue of ri > 0.

Reg­u­la­tions imposed by the High­way Depart­ment require that no two bill­boards be within five miles or less of each other. You’d like to place bill­boards at a sub­set of the sites so as to max­i­mize your total rev­enue, sub­ject to this restriction.

http://algorithms.tutorialhorizon.com/dynamic-programming-highway-billboard-problem/

Rod Cutting Problem

Given a rod of length n inches and a table of prices pi, i=1,2,…,n, write an algo­rithm to find the max­i­mum rev­enue rn obtain­able by cut­ting up the rod and sell­ing the pieces.
http://algorithms.tutorialhorizon.com/dynamic-programming-rod-cutting-problem/
http://www.geeksforgeeks.org/dynamic-programming-set-13-cutting-a-rod/

Saturday, June 18, 2016

House Robber

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

http://www.programcreek.com/2014/03/leetcode-house-robber-java/
http://www.programcreek.com/2014/05/leetcode-house-robber-ii-java/
http://www.programcreek.com/2015/03/leetcode-house-robber-iii-java/
http://shirleyisnotageek.blogspot.in/2016/06/house-robber-i-ii-and-iii.html

Monday, September 24, 2012

Find maximum stack possible with given slabs

You are given many slabs each with a length and a breadth. A slab i can be put on slab j if both dimensions of i are less than that of j. In this similar manner, you can keep on putting slabs on each other. Find the maximum stack possible which you can create out of the given slabs.Generalize this for n dimensions.

Thursday, March 15, 2012

Maximum sum path in a triangle

You have been given a triangle of numbers (as shown). You are supposed to start at the apex (top) and go to the base of the triangle by taking a path which gives the maximum sum. You have to print this maximum sum at the end. A path is formed by moving down 1 row at each step (to either of the immediately diagonal elements)

Maximise the value of Expression


Suppose you are given an expression E= x1 y1 x2 y2....yn-1 xn.
Where Xi belongs to natural number and Yi belongs to { +,*}

you need to parenthesize such that it maximize the value of E ?
Let's change Yi to { +,-,*,/}, then how to maximize E?
Now add % operator in that set..then how to maximize E?

Sunday, March 11, 2012

The Word Break Problem

Given an string and a dic­tio­nary of words, find out if the input string can be bro­ken into a space-separated sequence of one or more dic­tio­nary words.

Saturday, March 10, 2012

Maximum possible sum of Non-consecutive elements


There is an integer array consisting positive numbers only. Find maximum possible sum of elements such that there are no 2 consecutive elements present in the sum.

Example:
 If given array is (6, 4, 2, 8, 1), the answer will be 14 (8+6). This is the maximum sum we can obtain without taking two consecutive elements.

Method 1:
To solve these type of question, first thing is to find a recurring relation. In this case our recurring relation will tell the max sum till a given length. It means that we will get the max sum for running length of the array. If we denote the ith element as T(i) and max sum till ith element of the array as S(i), then
S(i) = MAX {S(i-1), S(i-2) + T(i) }

S(-1) = 0;
if i=0, S(i) = T(0);

Note: while developing this relationship, I assume array index is starting from 0.

sum2 = 0; sum = sum1 = array[0]; for(i=1; i<len; i++) { sum = MAX(sum2 + array[i], sum1); sum2 = sum1; sum1 = sum;}
Method 2:Dynamic Programming
This is a problem of Dynamic Programing and similar to longest increasing sub-sequence with the restriction that the sub-sequence cannot contain adjacent elements. The only difference is that in that problem, for an index j all the indices i, such that i < j were considered. But here we will consider i, such that i < j-1
The problem (and the longest sub-sequence as well) can be solved by modeling the array as a graph with an edge between (i,j) if j>i where j and i are the indices of the numbers but not when i = j-1 i.e. the two numbers are adjacent.

Pseudo Code:
  Create an array L[N]
for j = 1 to N:
    L(j) = a(j) + max{L(i) : (i; j) belongs to E}
return max L(j)

the base case will be when j=1 
max{ L(i): (i,j) belongs to E}= 0
 
The solution has O(N2) time complexity and O(N) space complexity.

Friday, March 2, 2012

Unique Paths in a grid

A robot is located at the top-left corner of a row x col grid The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid. How many possible unique paths are there?

Below is an example of 4x4 grid. Here from moving top-left to bottom right corner, we will have 20 unique paths.

1 1 1 1
1 2 3 4
1 3 6 10
1 4 10 20


Strategy:
Since we know that one can only move either down or right at any point in time so one can reach to cell (i,j) only from 2 possible locations:
  • One step right from cell (i-1,j)
  • One step down from cell (i,j-1)
So unique no of paths to reach any cell (i,j) will be equal to sum of unique no of paths to reach any cell (i-1,j) and unique no of paths to reach any cell (i,j-1). We can convert the same formula into code using 2 approaches:
  • Recursion / Backtracking
  • Dynamic programming.
In backtracking we will calculate the no of paths for same locations again and again but in Dynamic programming (DP) approach, we can use memoization and will get rid of calculating same locations again and again. For DP soluton just initialize a 2D array(sat paths) of size m x n with all elements as 1. And then apply the formula:


Paths[i][j] = paths[i][j-1] + paths[i-1][j]
After calculating the entire 2D array, just return paths[m][n]
Complexity: Since we are traversing each element just once, this solution has linear time complexity


Code:
int uniquePaths(int row, int col)

       int matrix[row][col];
        int i=0,j=0;
       // set the initial conditions
       for(i=0;i < row;i++)
          matrix[i][col-1]=1;

       for(j=0;j < col;j++)
          matrix[row-1][j]=1;
       // there is no path when we have reached
       //  the destination
       matrix[i][j]=0;
       
       // starting from the diagonal position and
       // moving upwards and leftwards
       for (i = row-2; i >= 0; i--)
       {
         for (int j = col-2; j >= 0; j--)
         {
              matrix[i][j] = matrix[i+1][j] + matrix[i][j+1];
         }
       }
       return matrix[0][0];
}
Alternatively,

 int no_of_paths(int width, int height)
 {
    //Creating paths
    int** paths = new int*[height];
    for(int i = 0; i < height; ++i)
        paths[i] = new int[width];
   
    int i,j;
   
    //Initializing paths
    for (i=0 ;i< width; i++)
    {
        for (j=0; j< height; j++)
            paths[i][j] = 1;
    }

    //Calculating paths  
    for (i=1 ;i< width; i++)
    {
        for (j=1; j< height; j++)
        {
            paths[i][j] = paths[i-1][j] + paths[i][j-1];
        }
    }
    //just for printing/debugging purpose  
    for (i=0 ;i< width; i++)
    {
        for (j=0; j< height; j++)
        {
            cout << paths[i][j] << " ";
        }
        cout << endl;
    }
       
    int res = paths[width-1][height-1];

    //Deleting paths  
    for(int i = 0; i < height; ++i) {
        delete [] paths[i];
    }
    delete [] paths;
   
    return res;
 }

Using 1d Array:

Instead of using a 2d array, We can have 1d Array with length as width
int no_of_paths(int width, int height)
 int i,j;
 int* no = new int[width];
 
 for (i=0 ;i< width; i++)
 {
  no[i] = 1;
  cout << "1 "; //just for printing/debugging purpose
 }
 cout << endl;     //just for printing/debugging purpose
 
 for (i=1 ;i< height; i++)
 {
  cout << no[0] << " ";     //just for printing/debugging purpose
  for (j=1; j< width; j++)
  {
   no[j] = no[j]+no[j-1];
   cout << no[j] << " "; //just for printing/debugging purpose
  }
  cout << endl;             //just for printing/debugging purpose
 }
 int res = no[width-1];
 
 delete [] no; 
 return res;
}

Tuesday, February 28, 2012

Coloring Houses

There are N houses in a row. Each house can be painted in either Red, Green or Blue color. The cost of coloring each house in each of the colors is different.

Find the color of each house such that no two adjacent house have the same color and the total cost of coloring all the houses is minimum.

Hint:The question intends to state that cost of painting any house in any color is different, so if cost of painting House 1 in Red is say, X then the cost of painting House 2 in red will some other value Y. It can be considered each house has different dimensions and hence cost of painting in each color is different, and the cost of paint for each house also varies 

Strategy:
This problem can be modeled as a Dynamic Programming problem. The DP equation can be given as
C[i][c] = H[c] + min(C[i-1][x]) 
                          x ∈ {Red, Blue, Green}
                          x ≠ c
Here C[i][c] is the cost of painting the row of houses ending at the ith house such that the ith house is painted in color 'c' and c is chosen such that the previous house is not in the same color. 

Food for Thought: An easier variant of the same problem, that can be solved using Greedy Approach will be when the cost of painting any house in any color is the same. In this case how will you paint the houses?

Wednesday, February 22, 2012

Compute Binomial Coefficient

Following are common definition of Binomial Coefficients.
1) A binomial coefficient C(n, k) can be defined as the coefficient of X^k in the expansion of (1 + X)^n.
2) A binomial coefficient C(n, k) also gives the number of ways, disregarding order, that k objects can be chosen from among n objects; more formally, the number of k-element subsets (or k-combinations) of an n-element set.
The Problem
Write a function that takes two parameters n and k and returns the value of Binomial Coefficient C(n, k). For example, your function should return 6 for n = 4 and k = 2, and it should return 10 for n = 5 and k = 2.

Monday, February 20, 2012

Minimum Number of Jumps to reach end

Given an array of integers where each element represents the max number of steps that can be made forward from that element. Write a function to return the minimum number of jumps to reach the end of the array (starting from the first element). If an element is 0, then cannot move through that element.
Example:
Input: arr[] = {1, 3, 5, 8, 9, 2, 6, 7, 6, 8, 9}
Output: 3 (1-> 3 -> 8 ->9)
First element is 1, so can only go to 3. Second element is 3, so can make at most 3 steps eg to 5 or 8 or 9.

http://www.programcreek.com/2014/03/leetcode-jump-game-java/
http://www.programcreek.com/2014/06/leetcode-jump-game-ii-java/

Method 1:Greedy Approach(Doesn't Gives Optimal Solution)

We Know that from ith location we can jump only maximum a[i] , so greedly we will keep goin & icrementing the jump untill we won't reach end of the array.
so in loop i=0 to size of array we will iterate through a[i] & w3ill check if a[i+j]+j ie greater then max or not if its true then we will update the max & repat the same logic. this we will reach to end of the array but doesn't gurantee that it will be optimal. e.g. fro above case it will return 3 jumps but for this case 1, 3, 5, 8, 9, 2, 6, 7, 6, 8, 9,1,1,1 which requires minimum number of jumps is 3 but this algo will produce jump 4.

Code:
#include <stdio.h>

int main()
{
int arr[]={1, 3, 5 ,8 ,9 ,2 ,6, 7, 6, 8, 9};
int size=sizeof(arr)/sizeof(int);

int i=0,jump=0,step,max,j;

while( i< size)
{ jump++; max=0; step=0;
 /*computes max distance it can cover in this jump*/
 for(j=1;j<=arr[i];j++)
    { if(arr[i+j]+j>max)
       {
        max=arr[i+j]+j;
        step=j;
       }
    }
i=i+step;
}

printf("%d ",jump);
getchar();
return 0;
}
Time Complexity O(N^2)
Space Compelxity O(1)

Method 2:Recursion
A naive approach is to start from the first element and recursively call for all the elements reachable from first element. The minimum number of jumps to reach end from first can be calculated using minimum number of jumps needed to reach end from the elements reachable from first.
minJumps(start, end) = Min ( minJumps(k, end) ) for all k reachable from start

#include <stdio.h>
#include <limits.h>

int minJumps(int arr[], int l, int h)
{
   // Base case: when source and destination are same
   if (h == l)
     return 0;

   // When nothing is reachable from the given source
   if (arr[l] == 0)
     return INT_MAX;

   // Traverse through all the points reachable from arr[l]. Recursively
   // get the minimum number of jumps needed to reach arr[h] from these
   // reachable points.
   int min = INT_MAX;
   for (int i = l+1; i <= h && i <= l + arr[l]; i++)
   {
       int jumps = minJumps(arr, i, h);
       if(jumps != INT_MAX && jumps + 1 < min)
           min = jumps + 1;
   }

   return min;
}

int main()
{
  int arr[] = {1, 3, 5, 8, 9, 2, 6, 7, 6, 8,9,1,1,1};
  int n = sizeof(arr)/sizeof(arr[0]);
  printf("Minimum number of jumps to reach end is %d ", minJumps(arr, 0, n-1));
  getchar();
  return 0;
}
 

Method 3:Dynamic Programing-Top Down 
In this method, we build a jumps[] array from left to right such that jumps[i] indicates the minimum number of jumps needed to reach arr[i] from arr[0]. Finally, we return jumps[n-1].

#include <stdio.h>
#include <limits.h>

int minJumps(int arr[], int n)
{
    int *jumps = new int[n];
    int i, j;

    if (n == 0 || arr[0] == 0)
        return INT_MAX;

    jumps[0] = 0;

    // Find the minimum number of jumps to reach arr[i]
    // from arr[0], and assign this value to jumps[i]
    for (i = 1; i < n; i++)
    {
        jumps[i] = INT_MAX;
        for (j = 0; j < i; j++)
        {
            if (i <= j + arr[j] && jumps[j] != INT_MAX)
            {
                 jumps[i] = jumps[j] + 1;
                 break;
            }
        }
    }
    return jumps[n-1];
}

int main()
{
    int arr[]= {1, 3, 5, 8, 9, 2, 6, 7, 6, 8,9,1,1,1};
    int size=sizeof(arr)/sizeof(int);
    printf("Minimum number of jumps to reach end is %d ", minJumps(arr,size));
    getchar();
    return 0;
}
Time Complexity:O(n2)
Method 4:Dynamic Programming-Botttom Up

Saturday, February 18, 2012

Maximum Sum Increasing Subsequence

Variation of LIS:
Given an integer array, how will you find out the increasing subsequence which gives the largest sum. For example,
50,23,1,67,30 in this subsequence a few possible increasing subsequences are
1)    23,30
2)    23,67
2)    50,67
3)    1,67
4)    1,30
5)    67
6)    30

but 50, 67 gives the maximum sum. How to find it
Note: In the above scenario however if we have 128 at index 0 then it will have the max sum although it is not forming longest LIS. 

Code:
int lis( int arr[], int n )
{
int *lis,*arr1, i, j, max = 0,max_value=0;

lis = (int*) malloc ( sizeof( int ) * n );
arr1 = (int*) malloc ( sizeof( int ) * n );

for ( i = 0; i < n; i++ )
lis[i] =1;


for ( i = 0; i < n; i++ )
arr1[i]=arr[i];


for ( i = 1; i < n; i++ )
  {
    for ( j = 0; j < i; j++ )
       { if ( arr[i] > arr[j] && lis[i] < lis[j] + 1)
             { lis[i] = lis[j] + 1;
                if(lis[i] > max)
                 { if (arr1[i] <(arr1[i]+arr1[j]))
                     arr1[i]=arr1[i]+arr1[j];
                    max=lis[i];
                  }
              }
        }
}

for(i=1;i < n;i++)
{ max_value=arr1[0];
if(arr1[i] > max_value)
max_value=arr1[i];
}

printf("\nThe Maximum sum is %d",max_value);
free( lis );
free( arr1 );

return max;
}

Balanced Partition [DP] / Tug of War

You have a set of n integers each in the range 0 ... K. Partition these integers into two subsets such that you minimize |S1 - S2|, where S1 and S2 denote the sums of the elements in each of the two subsets.

http://www.geeksforgeeks.org/dynamic-programming-set-18-partition-problem/

Variation 1:
Given a set of integers, the task is to divide it into two sets S1 and S2 such that the absolute difference between their sums is minimum.
If there is a set S with n elements, then if we assume Subset1 has m elements, Subset2 must have n-m elements and the value of abs(sum(Subset1) – sum(Subset2)) should be minimum.
Variation 2:
Given a set of n integers, divide the set in two subsets of n/2 sizes each such that the difference of the sum of two subsets is as minimum as possible. If n is even, then sizes of two subsets must be strictly n/2 and if n is odd, then size of one subset must be (n-1)/2 and size of other subset must be (n+1)/2.

Friday, February 17, 2012

Ugly Numbers

Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence
1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, …
shows the first 11 ugly numbers. By convention, 1 is included.
Write a program to find and print the 150′th ugly number.

Wednesday, February 15, 2012

Chocolate Distribution

You have n number of chocolates. Your best friend asks for the chocolate but you say that he can take only 1 or maximum 2 chocolates at a time.
Find the number of ways in which your friend can take all the chocolates in any number of times.

Tuesday, February 7, 2012

Maximum Sum from Coins in a line

In this game, which we will call the coins-in-a-line game, an even num­ber, n, of coins, of var­i­ous denom­i­na­tions from var­i­ous coun­tries, are placed in a line. Two play­ers, who we will call Alice and Bob, take turns remov­ing one of the coins from either end of the remain­ing line of coins. That is, when it is a player’s turn, he or she removes the coin at the left or right end of the line of coins and adds that coin to his or her col­lec­tion. The player who removes a set of coins with larger total value than the other player wins, where we assume that both Alice and Bob know the value of each coin.


All combinations of numbers that can compose a given number

Given a target number, and a series of candidate numbers, print out all combinations, so that the sum of candidate numbers equals to the target.

Here order is not important, so don’t print the duplicated combination.
e.g. target is 7, candidate is 2,3,6,7
output should be 7 and 3+2+2 (but not print 2+3+22+2+3)