Open In App

Number of ways to arrange N numbers which are in a range from 1 to K under given constraints.

Last Updated : 14 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given Four integers N, K, P and Q. The task is to calculate the number of ways to arrange N numbers which are in a range from 1 to K such that the first number is P, the last number is Q and no two adjacent numbers are consecutive. 

Examples: 

Input:  N = 4, K = 3, P = 2, Q = 3 
Output: 3
Explanation:
For N=4, K=3, P=2, Q=3,
ways are [2, 1, 2, 3], [2, 3, 1, 3], [2, 3, 2, 3]

Input:  N = 5, K = 3, P = 2, Q = 1 
Output: 5

Approach: The idea is to use Dynamic Programming to solve this problem. 

  • Let’s try to understand this by taking an example, N = 4, K = 3, P = 2, Q = 1. 
    We will observe all possible arrangements starting from P and try to find any pattern that can be useful to apply Dynamic programming. 
     
  • Below is the image showing all possible arrangements starting from P = 2. 
     

  • Let A be the array that consists of the number of nodes ending at Q at a particular level 
    A = { 0, 1, 1, 3 }
    Let B be the array that consists of the number of nodes NOT ending at Q at a particular level 
    B = {1, 1, 3, 5 }
  • On careful observation it may be noted that:
    1. A[i] = B[i-1] 
      Reason : 
      All the favourable nodes ( ending at Q ) will only be produced by non-favourable nodes(NOT ending at Q) of the previous level. 
       
    2. B[i] = A[i-1]*(K – 1) + B[i-1]*(K – 2) 
      Reason : 
      • For A[i-1]*(K – 1), some of the non-favourable nodes are produced by favourable nodes of the previous level, multiply by (K – 1) as each favourable node will produce K-1 non-favourable nodes 
         
      • For B[i-1]*(K – 2), rest of the non-favourable nodes are produced by non-favourable nodes of the previous level, multiply by (K-2), as one produced node is favourable, so we subtract 2 from this. 

C++




// C++ program to calculate Number of
// ways to arrange N numbers under
// given constraints.
#include <bits/stdc++.h>
using namespace std;
 
class element {
public:
    // For favourable nodes
    // (ending at Q)
    int A;
     
    // For Non-favourable nodes
    // (NOT ending at Q)
    int B;
};
 
// Function to print Total number
// of ways
void NumberOfWays(int n, int k, int p,
                                int q)
{
    element* dp = new element[n];
 
    // If the First number and the
    // last number is same.
    if (p == q) {
        dp[0].A = 1;
        dp[0].B = 0;
    }
    else
    {
        dp[0].A = 0;
        dp[0].B = 1;
    }
 
    // DP approach to find current state
    // with the help of previous state.
    for (int i = 1; i < n; i++)
    {
        dp[i].A = dp[i - 1].B;
        dp[i].B = (dp[i - 1].A * (k - 1))
                 + (dp[i - 1].B * (k - 2));
    }
     
    cout << dp[n - 1].A << endl;
 
    return;
}
 
// Driver code
int main()
{
    
   int N = 5;
   int K = 3;
   int P = 2;
   int Q = 1;
     
   // Function call
   NumberOfWays(N, K, P, Q);
}
    


Java




// Java program to calculate number of 
// ways to arrange N numbers under
// given constraints.
import java.io.*;
import java.util.*;
 
class GFG{
 
// Function to print Total number
// of ways
static void NumberOfWays(int n, int k,
                         int p, int q)
{
    int[][] dp = new int[n][2];
 
    // If the First number and the
    // last number is same.
    if (p == q)
    {
        dp[0][0] = 1;
        dp[0][1] = 0;
    }
    else
    {
        dp[0][0] = 0;
        dp[0][1] = 1;
    }
 
    // DP approach to find current state
    // with the help of previous state.
    for(int i = 1; i < n; i++)
    {
        dp[i][0] = dp[i - 1][1];
        dp[i][1] = (dp[i - 1][0] * (k - 1)) +
                   (dp[i - 1][1] * (k - 2));
    }
    System.out.println(dp[n - 1][0]);
}
 
// Driver Code
public static void main(String args[])
{
    int N = 5;
    int K = 3;
    int P = 2;
    int Q = 1;
         
    // Function call
    NumberOfWays(N, K, P, Q);
}
}
 
// This code is contributed by offbeat


Python3




# Python program to calculate Number of
# ways to arrange N numbers under
# given constraints.
 
class element:
    def __init__(self, A, B):
        # For favourable nodes
        # (ending at Q)
        self.A = A
        # For Non-favourable nodes
        # (NOT ending at Q)
        self.B = B
 
 
# Function to print Total number
# of ways
def NumberOfWays( n,  k,  p,  q):
    dp = [];
 
    # If the First number and the
    # last number is same.
    if (p == q):
        dp.append(element(1,0))
         
    else:
        dp.append(element(0,1))
         
    # DP approach to find current state
    # with the help of previous state.
    for i in range(1,n):
        dp.append(element(dp[i-1].B,(dp[i - 1].A * (k - 1)) + (dp[i - 1].B * (k - 2))))
    print(dp[n - 1].A);
 
    return;
 
# Driver code
N = 5;
K = 3;
P = 2;
Q = 1;
 
# Function call
NumberOfWays(N, K, P, Q);
    


C#




// C# code implementation
using System;
 
public class Element
{
    // For favourable nodes
    // (ending at Q)
    public int A { get; set; }
 
    // For Non-favourable nodes
    // (NOT ending at Q)
    public int B { get; set; }
}
 
public class Program
{
    // Function to print Total number
    // of ways
    public static void NumberOfWays(int n, int k, int p, int q)
    {
        Element[] dp = new Element[n];
 
        // If the First number and the
        // last number is same.
        if (p == q)
        {
            dp[0] = new Element { A = 1, B = 0 };
        }
        else
        {
            dp[0] = new Element { A = 0, B = 1 };
        }
 
        // DP approach to find current state
        // with the help of previous state.
        for (int i = 1; i < n; i++)
        {
            dp[i] = new Element
            {
                A = dp[i - 1].B,
                B = (dp[i - 1].A * (k - 1)) + (dp[i - 1].B * (k - 2))
            };
        }
 
        Console.WriteLine(dp[n - 1].A);
    }
 
    // Driver code
    public static void Main()
    {
        int N = 5;
        int K = 3;
        int P = 2;
        int Q = 1;
 
        // Function call
        NumberOfWays(N, K, P, Q);
    }
}


Javascript




// Function to print the total
// number of ways
function NumberOFWays(n, k, p, q){
    dp = [];
    for(let i = 0; i < n; i++){
        dp.push([0, 0]);
    }
 
    // If the first number and the
    // last number is same.
    if(p == q){
        dp[0][0] = 1;
        dp[0][1] = 0;
    }
    else{
        dp[0][0] = 0;
        dp[0][1] = 1;
    }
 
    // DP approach to find current state
    // with help of previous state
 
    for(let i = 1; i < n; i++){
        dp[i][0] = dp[i-1][1];
        dp[i][1] = (dp[i-1][0]*(k-1)) + (dp[i-1][1]*(k-2));
    }
 
    console.log(dp[n-1][0]);
}
 
 
// Driver code
let N = 5;
let K = 3;
let P = 2;
let Q = 1;
 
// Function call
NumberOFWays(N, K, P, Q);
 
 
// This code is contributed By Aditya Sharma


Output

5

Time Complexity: O(N).
Auxiliary Space: O(N) 

Efficient approach : space optimization O(1)

In previous approach dp[i] is depend only upon dp[i-1] so we can replace these dp[i] to curr and dp[i-1] to prev to determine the current and previous computation.

Implementation Steps:

  • Take two variables prev_A and prev_B to keep track of previous 2 numbers  and curr_A and curr_B for current two numbers.
  • Initialize prev_A and prev_B by checking first and last numbers are same or not.
  • Now iterate over subproblems to determine curr_A and curr_B from previous computations.
  • At last return answer stored in curr_A.

Implementation:

C++




// C++ program to calculate Number of
// ways to arrange N numbers under
// given constraints.
#include <bits/stdc++.h>
using namespace std;
 
// Function to print Total number
// of ways
void NumberOfWays(int n, int k, int p,
                                int q)
{
    int prev_A, prev_B;
     
    // If the First number and the
    // last number is same.
    if (p == q) {
        prev_A = 1;
        prev_B = 0;
    }
    else
    {
        prev_A = 0;
        prev_B = 1;
    }
 
    int curr_A, curr_B;
    // DP approach to find current state
    // with the help of previous state.
    for (int i = 1; i < n; i++)
    {
        curr_A = prev_B;
        curr_B = (prev_A * (k - 1)) + (prev_B * (k - 2));
        prev_A = curr_A;
        prev_B = curr_B;
    }
     
    cout << curr_A << endl;
 
    return;
}
 
// Driver code
int main()
{
     
  int N = 5;
  int K = 3;
  int P = 2;
  int Q = 1;
 
  // Function call
  NumberOfWays(N, K, P, Q);
}


Java




import java.util.*;
 
class Main {
 
    // Function to print Total number
    // of ways
    static void numberOfWays(int n, int k, int p, int q) {
        int prevA, prevB;
 
        // If the First number and the
        // last number is same.
        if (p == q) {
            prevA = 1;
            prevB = 0;
        } else {
            prevA = 0;
            prevB = 1;
        }
 
        int currA = 0;
        int currB = 0;
        // DP approach to find current state
        // with the help of previous state.
        for (int i = 1; i < n; i++) {
            currA = prevB;
            currB = (prevA * (k - 1)) + (prevB * (k - 2));
            prevA = currA;
            prevB = currB;
        }
 
        System.out.println(currA);
        return;
    }
 
    // Driver code
    public static void main(String[] args) {
 
        int N = 5;
        int K = 3;
        int P = 2;
        int Q = 1;
 
        // Function call
        numberOfWays(N, K, P, Q);
    }
}


Python




# Python program to calculate Number of
# ways to arrange N numbers under
# given constraints.
 
# Function to print Total number
# of ways
def NumberOfWays(n, k, p, q):
    # If the First number and the
    # last number is same.
    if p == q:
        prev_A = 1
        prev_B = 0
    else:
        prev_A = 0
        prev_B = 1
 
    # DP approach to find current state
    # with the help of previous state.
    for i in range(1, n):
        curr_A = prev_B
        curr_B = (prev_A * (k - 1)) + (prev_B * (k - 2))
        prev_A = curr_A
        prev_B = curr_B
 
    print(curr_A)
 
# Driver code
N = 5
K = 3
P = 2
Q = 1
 
# Function call
NumberOfWays(N, K, P, Q)


C#




using System;
 
public class Element
{
    // For favourable nodes
    // (ending at Q)
    public int A { get; set; }
 
    // For Non-favourable nodes
    // (NOT ending at Q)
    public int B { get; set; }
}
 
public class Program
{
    // Function to print Total number
    // of ways
    public static void NumberOfWays(int n, int k, int p, int q)
    {
        Element[] dp = new Element[n];
 
        // If the First number and the
        // last number is same.
        if (p == q)
        {
            dp[0] = new Element { A = 1, B = 0 };
        }
        else
        {
            dp[0] = new Element { A = 0, B = 1 };
        }
 
        // DP approach to find current state
        // with the help of previous state.
        for (int i = 1; i < n; i++)
        {
            dp[i] = new Element
            {
                A = dp[i - 1].B,
                B = (dp[i - 1].A * (k - 1)) + (dp[i - 1].B * (k - 2))
            };
        }
 
        Console.WriteLine(dp[n - 1].A);
    }
 
    // Driver code
    public static void Main()
    {
        int N = 5;
        int K = 3;
        int P = 2;
        int Q = 1;
 
        // Function call
        NumberOfWays(N, K, P, Q);
    }
}


Javascript




// Function to print Total number of ways
function NumberOfWays(n, k, p, q) {
    // If the First number and the last number is same.
    let prev_A, prev_B;
    if (p == q) {
        prev_A = 1;
        prev_B = 0;
    } else {
        prev_A = 0;
        prev_B = 1;
    }
 
    // DP approach to find current state
    // with the help of previous state.
    for (let i = 1; i < n; i++) {
        let curr_A = prev_B;
        let curr_B = (prev_A * (k - 1)) + (prev_B * (k - 2));
        prev_A = curr_A;
        prev_B = curr_B;
    }
 
    console.log(prev_A);
}
 
// Driver code
let N = 5;
let K = 3;
let P = 2;
let Q = 1;
 
// Function call
NumberOfWays(N, K, P, Q);


Output

5

Time Complexity: O(N).
Auxiliary Space: O(1) 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads