给定大小为N的字符串str ,由前N个字母和大小为N * N的矩阵mat []组成,其中mat [i] [j]表示将字符中的第i个字符放置在字符串第j个字符之前的开销。该任务是找到生成给定字符串的任何排列的最低成本。
例子:
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: 8
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
幼稚的方法:幼稚的想法是生成给定字符串的所有可能排列,并找出每个排列的代价。然后在所有可能的成本中打印最低成本。
时间复杂度: O(N * N!)
辅助空间: O(N!)
高效的方法:为了优化上述方法,其思想是使用带位屏蔽的动态编程。请注意,所有字符都是不同的,并且只能有26个字母。因此,请使用遮罩存储每个字符的存在。步骤如下:
- 遍历字符串的所有字符,并将每个字符放置在每个位置(如果可用),即在掩码中设置该位。
- 然后,将字符放置在当前位置并计算放置字符的成本。
- 通过翻转当前字符的位移动到下一个位置。
- 在每次迭代中,掩码代表当前位置的可用字符数。
- 完成上述步骤后,在所有计算出的成本中打印最低成本。
下面是上述方法的实现:
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
8
时间复杂度: O(N * 2 N )
辅助空间: O(N * 2 N )