大小N组成的第一N字母的和的大小N * N的矩阵垫[]的定的字符串str其中垫[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
Javascript
8
时间复杂度: O(N*2 N )
辅助空间: O(N*2 N )
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。