Skip to content
Related Articles

Related Articles

Minimum cost to generate any permutation of the given string
  • Last Updated : 16 Dec, 2020

Given string str of size N consisting of the first N alphabets and a matrix mat[] of size N*N where mat[i][j] represents the cost of placing ith character of the alphabet before the jth character in the string. The task is to find the minimum cost to generate any permutation of the given string.

Examples: 

Input:str = “abcde”, mat[][]= {{0, 5, 1, 5, 3}, {4, 0, 9, 4, 2}, {7, 9, 0, 10, 7}, {1, 2, 8, 0, 2}, {3, 9, 7, 7, 0}} 
Output:
Explanation: 
Permutation ‘dbeac’ can be generated at a minimum cost of 8. 
Cost of placing d = 0 (since there is no prev character) 
Cost of placing b after d = mat[4][2] = 2 
Cost of placing e after b = mat[2][5] = 2 
Cost of placing a after e = mat[5][1] = 3 
Cost of placing c after a = mat[1][3] = 1 
Total cost = 2 + 2 + 3 + 1 = 8 

Input: str = “abcde”, mat[][] = {{0, 9, 4, 8, 10}, {7, 0, 9, 5, 5}, {2, 8, 0, 4, 1}, {4, 10, 5, 0, 5}, {4, 3, 4, 7, 0 }} 
Output: 13 

Naive Approach: The naive idea is to generate all possible permutations of the given string and find the cost of every permutation. Then print the minimum cost among all possible costs.



Time Complexity: O(N*N!) 
Auxiliary Space: O(N!)

Efficient Approach: To optimize the above approach the idea is to use Dynamic Programming with Bit Masking. Observe that all the characters are distinct and there are only 26 alphabets possible. So use a mask to store the presence of each character. Below are the steps: 

  1. Iterate through all characters of the string and place each character at each position if it is available i.e., the bit is set in the mask.
  2. Then, place the character in the current position and calculate the cost of placing the character.
  3. Move to the next position by flipping the bit of the current character.
  4. At each iteration, the mask represents the number of available characters for the current position.
  5. After completing the above steps, print the minimum cost among all the costs calculated.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function that returns true
// if the current bit is set
bool check(int mask, int i)
{
    int c = (mask & (1 << i));
    return c != 0;
}
 
// Function to find the minimum cost
// to form any permutation of string s
int solve(vector<vector<int>> a, string s,
          int n, int prev, int mask,
          vector<vector<int>> dp)
{
     
    // Base Case
    if (mask == 0)
        return 0;
 
    // Return the precomputed state
    if (dp[mask][prev + 1] != -1)
        return dp[mask][prev + 1];
 
    int ans = 10000;
 
    // Iterate over the string and
    // check all possible characters
    // available for current position
    for(int i = 0; i < s.length(); i++)
    {
        int id = s[i] - 'a';
         
        // Check if character can be
        // placed at current position
        if (check(mask, id))
        {
             
            // As there is no previous
            // character so the cost
            // for 1st character is 0
            if (prev == -1)
            {
                ans = min(ans, solve(a, s, n, id,
                                     mask ^ (1 << id), dp));
            }
 
            // Find the cost of current
            // character and move to next
            // position
            else
            {
                ans = min(ans, a[prev][id] +
                          solve(a, s, n, id,
                                mask ^ (1 << id), dp));
            }
        }
    }
 
    // Store the answer for each
    // current state
    dp[mask][prev + 1] = ans;
    return ans;
}
 
// Function that generates any
// permutation of the given
// string with minimum cost
void generatePermutation(int mask, int n,
                         vector<vector<int>> a,
                         string s)
{
     
    // Initialize dp table
    vector<vector<int>> dp((1 << n) + 5 ,
           vector<int> (n + 5, -1));
 
    // Set all the bits of the
    // current character id
    for(int i = 0; i < s.length(); i++)
    {
        int id = s[i] - 'a';
        mask |= (1 << id);
    }
     
    // Minimum cost of generating
    // the permutation
    cout << solve(a, s, n, -1, mask, dp)
         << endl;
}
 
// Driver Code  
int main()
{
    int N = 5;
    string str = "abcde";
 
    vector<vector<int>> mat = { { 0, 5, 1, 5, 3 },
                                { 4, 0, 9, 4, 2 },
                                { 7, 9, 0, 10, 7 },
                                { 1, 2, 8, 0, 2 },
                                { 3, 9, 7, 7, 0 } };
 
    // Function Call
    generatePermutation(0, N, mat, str);
     
    return 0;
}
 
// This code is contributed by divyeshrabadiya07

Java




// Java program for the above approach
 
import java.util.*;
 
public class Main {
 
    // Function to find the minimum cost
    // to form any permutation of string s
    public static int solve(
        int a[][], String s, int n,
        int prev, int mask, int[][] dp)
    {
        // Base Case
        if (mask == 0)
            return 0;
 
        // Return the precomputed state
        if (dp[mask][prev + 1] != -1)
            return dp[mask][prev + 1];
 
        int ans = 10000;
 
        // Iterate over the string and
        // check all possible characters
        // available for current position
        for (int i = 0; i < s.length(); i++) {
 
            int id = s.charAt(i) - 'a';
 
            // Check if character can be
            // placed at current position
            if (check(mask, id)) {
 
                // As there is no previous
                // character so the cost
                // for 1st character is 0
                if (prev == -1) {
 
                    ans
                        = Math.min(ans,
                                   solve(
                                       a, s,
                                       n, id,
                                       mask ^ (1 << id),
                                       dp));
                }
 
                // Find the cost of current
                // character and move to next
                // position
                else {
                    ans = Math.min(
                        ans,
                        a[prev][id]
                            + solve(
                                  a, s,
                                  n, id,
                                  mask ^ (1 << id),
                                  dp));
                }
            }
        }
 
        // Store the answer for each
        // current state
        dp[mask][prev + 1] = ans;
        return ans;
    }
 
    // Function that returns true
    // if the current bit is set
    public static boolean
    check(int mask, int i)
    {
        int c = (mask & (1 << i));
        return c != 0;
    }
 
    // Function that generates any
    // permutation of the given
    // string with minimum cost
    static void generatePermutation(
        int mask, int n, int a[][],
        String s)
    {
 
        // Initialize dp table
        int dp[][] = new int[(1 << n) + 5][n + 5];
 
        for (int i[] : dp)
            Arrays.fill(i, -1);
 
        // Set all the bits of the
        // current character id
        for (int i = 0;
             i < s.length(); i++) {
 
            int id = s.charAt(i) - 'a';
            mask |= (1 << id);
        }
 
        // Minimum cost of generating
        // the permutation
        System.out.println(solve(
            a, s, n, -1, mask, dp));
    }
 
    // Driver Code
    public static void main(String args[])
    {
        int N = 5;
 
        String str = "abcde";
 
        int mat[][] = { { 0, 5, 1, 5, 3 },
                        { 4, 0, 9, 4, 2 },
                        { 7, 9, 0, 10, 7 },
                        { 1, 2, 8, 0, 2 },
                        { 3, 9, 7, 7, 0 } };
 
        // Function Call
        generatePermutation(0, N, mat, str);
    }
}

Python3




# Python3 program for the
# above approach
 
# Function to find the
# minimum cost to form
# any permutation of
# string s
def solve(a, s, n, prev,
          mask, dp):
    # Base Case
    if (mask == 0):
        return 0;
 
    # Return the precomputed state
    if (dp[mask][prev + 1] != -1):
        return dp[mask][prev + 1];
 
    ans = 10000;
 
    # Iterate over the string and
    # check all possible characters
    # available for current position
    for i in range(len(s)):
        id = ord(s[i]) - ord('a');
 
        # Check if character can be
        # placed at current position
        if (check(mask, id)):
 
            # As there is no previous
            # character so the cost
            # for 1st character is 0
            if (prev == -1):
                ans = min(ans,
                      solve(a, s,
                            n, id,
                            mask ^ (1 <<
                            id), dp));
 
 
            # Find the cost of current
            # character and move to next
            # position
            else:
                ans = min(ans, a[prev][id] +
                      solve(a, s, n,
                            id, mask ^
                            (1 << id), dp));
 
    # Store the answer for each
    # current state
    dp[mask][prev + 1] = ans;
    return ans;
 
 
# Function that returns
# True if the current
# bit is set
def check(mask, i):
   
    c = (mask & (1 << i));
    return c != 0;
 
# Function that generates any
# permutation of the given
# string with minimum cost
def generatePermutation(mask, n,
                        a, s):
 
    # Initialize dp table
    dp = [[-1 for i in range(n + 5)]
              for j in range((1 << n) + 5)]
 
    # Set all the bits of the
    # current character id
    for i in range(len(s)):
        id = ord(s[i]) - ord('a');
        mask |= (1 << id);
 
    # Minimum cost of generating
    # the permutation
    print(solve(a, s, n,
                -1, mask, dp));
 
# Driver Code
if __name__ == '__main__':
   
    N = 5;
    str = "abcde";
    mat = [[0, 5, 1, 5, 3],
           [4, 0, 9, 4, 2],
           [7, 9, 0, 10, 7],
           [1, 2, 8, 0, 2],
           [3, 9, 7, 7, 0]];
 
    # Function Call
    generatePermutation(0, N,
                        mat, str);
 
# This code is contributed by gauravrajput1

C#




// C# program for the
// above approach
using System;
class GFG{
 
// Function to find the minimum cost
// to form any permutation of string s
public static int solve(int[,]a, String s, int n,
                        int prev, int mask, int[,] dp)
{
  // Base Case
  if (mask == 0)
    return 0;
 
  // Return the precomputed state
  if (dp[mask,prev + 1] != -1)
    return dp[mask, prev + 1];
 
  int ans = 10000;
 
  // Iterate over the string and
  // check all possible characters
  // available for current position
  for (int i = 0;
           i < s.Length; i++)
  {
    int id = s[i] - 'a';
 
    // Check if character can be
    // placed at current position
    if (check(mask, id))
    {
      // As there is no previous
      // character so the cost
      // for 1st character is 0
      if (prev == -1)
      {
        ans = Math.Min(ans,
                       solve(a, s, n, id,
                             mask ^ (1 << id), dp));
      }
 
      // Find the cost of current
      // character and move to next
      // position
      else
      {
        ans = Math.Min(ans, a[prev,id] +
                       solve(a, s, n, id,
                             mask ^ (1 << id), dp));
      }
    }
  }
 
  // Store the answer for each
  // current state
  dp[mask, prev + 1] = ans;
  return ans;
}
 
// Function that returns true
// if the current bit is set
public static bool check(int mask, int i)
{
  int c = (mask & (1 << i));
  return c != 0;
}
 
// Function that generates any
// permutation of the given
// string with minimum cost
static void generatePermutation(int mask, int n,
                                int[,]a, String s)
{
  // Initialize dp table
  int [,]dp = new int[(1 << n) + 5,
                      n + 5];
 
  for(int i = 0;
          i < (1 << n) + 5; i++)
    for(int j = 0;
            j < n + 5; j++)
      dp[i, j] = -1;
   
  // Set all the bits of the
  // current character id
  for (int i = 0;
       i < s.Length; i++)
  {
    int id = s[i] - 'a';
    mask |= (1 << id);
  }
 
  // Minimum cost of generating
  // the permutation
  Console.WriteLine(solve(a, s, n,
                          -1, mask, dp));
}
 
// Driver Code
public static void Main(String []args)
{
  int N = 5;
  String str = "abcde";
  int [,]mat = {{0, 5, 1, 5, 3},
                {4, 0, 9, 4, 2},
                {7, 9, 0, 10, 7},
                {1, 2, 8, 0, 2},
                {3, 9, 7, 7, 0}};
 
  // Function Call
  generatePermutation(0, N, mat, str);
}
}
 
// This code is contributed by Rajput-Ji
Output: 
8

 

Time Complexity: O(N*2N
Auxiliary Space: O(N*2N)

My Personal Notes arrow_drop_up
Recommended Articles
Page :