📜  生成给定字符串的任何排列的最低成本

📅  最后修改于: 2021-09-06 11:33:04             🧑  作者: Mango

大小N组成的第一N字母的和的大小N * N的矩阵垫[]的定字符串str其中垫[i] [j]表示将i中的字母的字符的第j字符的字符串中的成本.任务是找到生成给定字符串的任何排列的最低成本。

例子:

朴素的方法:朴素的想法是生成给定字符串的所有可能排列并找到每个排列的成本。然后打印所有可能成本中的最小成本。

时间复杂度: O(N*N!)
辅助空间: O(N!)

有效的方法:为了优化上述方法,想法是使用带有位掩码的动态编程。观察到所有字符都是不同的,并且只有 26 个可能的字母。所以使用掩码来存储每个字符的存在。以下是步骤:

  1. 遍历字符串的所有字符并将每个字符放置在每个位置(如果可用),即该位在掩码中设置。
  2. 然后,将字符放置在当前位置并计算放置字符的成本。
  3. 通过翻转当前字符的位移动到下一个位置。
  4. 在每次迭代中,掩码表示当前位置的可用字符数。
  5. 完成上述步骤后,打印所有计算出的成本中的最小成本。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
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> a, string s,
          int n, int prev, int mask,
          vector> 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> a,
                         string s)
{
     
    // Initialize dp table
    vector> dp((1 << n) + 5 ,
           vector (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> 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


Javascript


输出:
8

时间复杂度: O(N*2 N )
辅助空间: O(N*2 N )

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live