# Minimum cost to sort strings using reversal operations of different costs

Given an array of strings and costs of reversing all strings, we need to sort the array. We cannot move strings in array, only string reversal is allowed. We need to reverse some of the strings in such a way that all strings make a lexicographic order and cost is also minimized. If it is not possible to sort strings in any way, output not possible.
Examples:

```Input  : arr[] = {“aa”, “ba”, “ac”},
reverseCost[] = {1, 3, 1}
Output : Minimum cost of sorting = 1
Explanation : We can make above string array sorted
by reversing one of 2nd or 3rd string, but reversing
2nd string cost 3, so we will reverse 3rd string to
make string array sorted with a cost 1 which is
minimum.
```

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

We can solve this problem using dynamic programming. We make a 2D array for storing the minimum cost of sorting.

```dp[i][j] represents the minimum cost to make first i
strings sorted.
j = 1 means i'th string is reversed.
j = 0 means i'th string is not reversed.

Value of dp[i][j] is computed using dp[i-1][1] and
dp[i-1][0].

Computation of dp[i][0]
If arr[i] is greater than str[i-1], we update dp[i][0]
by dp[i-1][0]
If arr[i] is greater than reversal of previous string
we update dp[i][0] by dp[i-1][1]

Same procedure is applied to compute dp[i][1], we
reverse str[i] before applying the procedure.

At the end we will choose minimum of dp[N-1][0] and
dp[N-1][1] as our final answer if both of them not
updated yet even once, we will flag that sorting is
not possible.
```

Below is the implementation of above idea.

## C/C++

```// C++ program to get minimum cost to sort
// strings by reversal operation
#include <bits/stdc++.h>
using namespace std;

// Returns minimum cost for sorting arr[]
// using reverse operation. This function
// returns -1 if it is not possible to sort.
int minCost(string arr[], int cost[], int N)
{
// dp[i][j] represents the minimum cost to
// make first i strings sorted.
// j = 1 means i'th string is reversed.
// j = 0 means i'th string is not reversed.
int dp[N][2];

//  initializing dp array for first string
dp[0][0] = 0;
dp[0][1] = cost[0];

//  getting array of reversed strings
string revStr[N];
for (int i = 0; i < N; i++)
{
revStr[i] = arr[i];
reverse(revStr[i].begin(), revStr[i].end());
}

string curStr;
int curCost;

//  looping for all strings
for (int i = 1; i < N; i++)
{
// Looping twice, once for string and once
// for reversed string
for (int j = 0; j < 2; j++)
{
dp[i][j] = INT_MAX;

// getting current string and current
// cost according to j
curStr = (j == 0) ? arr[i] : revStr[i];
curCost = (j == 0) ? 0 : cost[i];

// Update dp value only if current string
// is lexicographically larger
if (curStr >= arr[i - 1])
dp[i][j] = min(dp[i][j], dp[i-1][0] + curCost);
if (curStr >= revStr[i - 1])
dp[i][j] = min(dp[i][j], dp[i-1][1] + curCost);
}
}

//  getting minimum from both entries of last index
int res = min(dp[N-1][0], dp[N-1][1]);

return (res == INT_MAX)? -1 : res;
}

//  Driver code to test above methods
int main()
{
string arr[] = {"aa", "ba", "ac"};
int cost[] = {1, 3, 1};
int N = sizeof(arr) / sizeof(arr[0]);

int res = minCost(arr, cost, N);
if (res == -1)
cout << "Sorting not possible\n";
else
cout << "Minimum cost to sort strings is "
<< res;
}
```

## Python

```# Python program to get minimum cost to sort
# strings by reversal operation

# Returns minimum cost for sorting arr[]
# using reverse operation. This function
# returns -1 if it is not possible to sort.
def ReverseStringMin(arr, reverseCost, n):

# dp[i][j] represents the minimum cost to
# make first i strings sorted.
# j = 1 means i'th string is reversed.
# j = 0 means i'th string is not reversed.

dp = [[float("Inf")] * 2  for i in range(n)]

# initializing dp array for first string
dp[0][0] = 0

dp[0][1] = reverseCost[0]

# getting array of reversed strings
rev_arr = [i[::-1] for i in arr]

# looping for all strings
for i in range(1, n):

# Looping twice, once for string and once
# for reversed string
for j in range(2):

# getting current string and current
# cost according to j
curStr = arr[i] if j==0 else rev_arr[i]

curCost = 0 if j==0 else reverseCost[i]

# Update dp value only if current string
# is lexicographically larger
if (curStr >= arr[i - 1]):

dp[i][j] = min(dp[i][j], dp[i-1][0] + curCost)

if (curStr >= rev_arr[i - 1]):

dp[i][j] = min(dp[i][j], dp[i-1][1] + curCost)

#  getting minimum from both entries of last index
res = min(dp[n-1][0], dp[n-1][1])

return res if  res != float("Inf") else -1

#  Driver code
def main():

arr = ["aa", "ba", "ac"]

reverseCost = [1, 3, 1]

n = len(arr)

dp = [float("Inf")] * n

res = ReverseStringMin(arr, reverseCost,n)

if res != -1 :

print "Minimum cost to sort sorting is" , res

else :
print "Sorting not possible"

if __name__ == '__main__':
main()

#This code is contributed by Neelam Yadav
```

Output:

```Minimum cost to sort strings is 1
```

This article is contributed by Utkarsh Trivedi. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

# GATE CS Corner    Company Wise Coding Practice

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.
4.2 Average Difficulty : 4.2/5.0
Based on 17 vote(s)