Minimizing the cost to convert A to B with Flips
Last Updated :
29 Jan, 2024
Given two binary strings A and B both of the same length and two integers x and y. In one operation, we can select two indices l and r and flip the number at A[l] and A[r] i.e. 1 to 0 and 0 to 1. If l+1 = r, the cost of this operation is x, otherwise the cost is y. The task is to find the minimum cost to convert A to B by applying the above operations or print -1 if it is impossible to do so.
Examples:
Input: A = "01001", B = "00101", x = 8, y = 9
Output: 8
Explanation: select indices 1 and 2 and apply the operation which costs 8
Input: A = "10000011000001", B = "00000000000000", x = 8, y = 9
Output: 17
Explanation: Select indices 6 and 7 and apply the operation, so cost = 8 and select index 0 and 13 and apply the operation with cost = 9. So total cost = 8 + 9 = 17
Input: A = "01000", B = "11011", x = 7, y = 2
Output: -1
Explanation: It is impossible to convert string a to b
Approach: To solve the problem, follow the below idea:
The approach is to use Dynamic programming to find the minimum cost of converting string a to string b by applying the specified operations.
Steps to solve the problem:
- Define a recursive function, say solve(idx, flag) to calculate the minimum cost to convert the substring of A starting from index idx to the corresponding substring of B.
- The flag is true if we have already changed some character before with a cost of y and now, we can change this character without any cost.
- Maintain a vector v to store all the indices where the character in A differs from B.
- At any index i, we have 2 choices:
- Choice 1: Change the current index and the next index by changing adjacent bits starting from v[idx] to v[idx+1] and incurring a cost of (v[idx + 1] - v[idx]) * x
- Choice 2: Change the current index with cost = y and move to the next index with the advantage of changing any other index in future free of cost.
- Explore all the choices and return the answer as dp[0][0].
Below is the code for the above approach:
C++
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll N = 5e3 + 15;
// dp table for memoization
ll dp[N][2];
ll n, x, y, z;
string A, B;
// vector to store indices which differ in string A and B
vector<ll> v;
ll solve(ll idx, bool flag)
{
if (idx > z)
return 1e10;
if (idx == z)
return 0;
if (dp[idx][flag] != -1)
return dp[idx][flag];
ll cost = 0;
// If the current index is not the last index of A
if (idx + 1 < z) {
// We cannot change the current index free of cost
if (!flag)
cost = min(solve(idx + 1, 1) + y,
solve(idx + 2, 0)
+ (v[idx + 1] - v[idx]) * x);
// We can change the current index free of cost
else
cost = min(solve(idx + 1, 0),
solve(idx + 2, 1)
+ (v[idx + 1] - v[idx]) * x);
}
// If the current index is the last index of A
else {
// We have to change the current index with some
// previous operation
cost = solve(idx + 1, 0);
}
return dp[idx][flag] = cost;
}
int main()
{
A = "10000011000001";
B = "00000000000000";
x = 8;
y = 9;
n = A.size();
for (ll i = 0; i < n; i++)
if (A[i] != B[i])
v.push_back(i);
z = v.size();
// If the number of different indices is odd, then it is
// impossible to convert A to B
if (z % 2) {
cout << -1;
}
else {
for (int i = 0; i <= z; i++) {
dp[i][1] = dp[i][0] = -1;
}
cout << solve(0, 0);
}
return 0;
}
Java
import java.util.*;
public class Solution {
static int N = 5 * 1000 + 15;
static int[][] dp = new int[N][2];
static int n, x, y, z;
static String A, B;
static int[] v;
static int solve(int idx, int flag)
{
if (idx > z) {
return (int)1e10;
}
if (idx == z) {
return 0;
}
if (dp[idx][flag] != -1) {
return dp[idx][flag];
}
int cost = 0;
// If the current index is not the last index of A
if (idx + 1 < z) {
if (flag == 0) {
// We cannot change the current index free
// of cost
cost = Math.min(solve(idx + 1, 1) + y,
solve(idx + 2, 0)
+ (v[idx + 1] - v[idx])
* x);
}
else {
// We can change the current index free of
// cost
cost = Math.min(solve(idx + 1, 0),
solve(idx + 2, 1)
+ (v[idx + 1] - v[idx])
* x);
}
}
else {
// If the current index is the last index of A
// We have to change the current index with some
// previous operation
cost = solve(idx + 1, 0);
}
dp[idx][flag] = cost;
return cost;
}
public static void main(String[] args)
{
A = "10000011000001";
B = "00000000000000";
x = 8;
y = 9;
n = A.length();
v = new int[n];
// Populating the array 'v' with indices where A and
// B differ
int count = 0;
for (int i = 0; i < n; i++) {
if (A.charAt(i) != B.charAt(i)) {
v[count++] = i;
}
}
z = count;
// If the number of different indices is odd, then
// it is impossible to convert A to B
if (z % 2 == 1) {
System.out.println(-1);
}
else {
// Initializing the dp array with -1
for (int i = 0; i <= z; i++) {
Arrays.fill(dp[i], -1);
}
// Printing the result of the solve function
System.out.println(solve(0, 0));
}
}
}
Python3
import sys
sys.setrecursionlimit(10**6)
N = 5 * 10**3 + 15
# dp table for memoization
dp = [[-1, -1] for _ in range(N)]
n, x, y, z = 0, 0, 0, 0
A, B = "", ""
# vector to store indices which differ in string A and B
v = []
def solve(idx, flag):
global dp, x, y, z, v
if idx > z:
return 1e10
if idx == z:
return 0
if dp[idx][flag] != -1:
return dp[idx][flag]
cost = 0
# If the current index is not the last index of A
if idx + 1 < z:
# We cannot change the current index free of cost
if not flag:
cost = min(solve(idx + 1, 1) + y,
solve(idx + 2, 0) + (v[idx + 1] - v[idx]) * x)
# We can change the current index free of cost
else:
cost = min(solve(idx + 1, 0),
solve(idx + 2, 1) + (v[idx + 1] - v[idx]) * x)
# If the current index is the last index of A
else:
# We have to change the current index with some
# previous operation
cost = solve(idx + 1, 0)
dp[idx][flag] = cost
return cost
def main():
global A, B, x, y, n, v, z, dp
A = "10000011000001"
B = "00000000000000"
x = 8
y = 9
n = len(A)
for i in range(n):
if A[i] != B[i]:
v.append(i)
z = len(v)
# If the number of different indices is odd, then it is
# impossible to convert A to B
if z % 2:
print(-1)
else:
for i in range(z + 1):
dp[i][1] = dp[i][0] = -1
print(solve(0, 0))
if __name__ == "__main__":
main()
C#
using System;
using System.Collections.Generic;
class Program
{
const int N = 5_015;
// dp table for memoization
static long[,] dp = new long[N, 2];
static int n, x, y, z;
static string A, B;
// vector to store indices which differ in string A and B
static List<int> v = new List<int>();
static long Solve(int idx, bool flag)
{
if (idx > z)
return (long)1e10;
if (idx == z)
return 0;
if (dp[idx, Convert.ToInt32(flag)] != -1)
return dp[idx, Convert.ToInt32(flag)];
long cost = 0;
// If the current index is not the last index of A
if (idx + 1 < z)
{
// We cannot change the current index free of cost
if (!flag)
cost = Math.Min(Solve(idx + 1, true) + y,
Solve(idx + 2, false) + (v[idx + 1] - v[idx]) * x);
// We can change the current index free of cost
else
cost = Math.Min(Solve(idx + 1, false),
Solve(idx + 2, true) + (v[idx + 1] - v[idx]) * x);
}
// If the current index is the last index of A
else
{
// We have to change the current index with some
// previous operation
cost = Solve(idx + 1, false);
}
return dp[idx, Convert.ToInt32(flag)] = cost;
}
static void Main()
{
A = "10000011000001";
B = "00000000000000";
x = 8;
y = 9;
n = A.Length;
for (int i = 0; i < n; i++)
if (A[i] != B[i])
v.Add(i);
z = v.Count;
// If the number of different indices is odd, then it is
// impossible to convert A to B
if (z % 2 != 0)
{
Console.WriteLine(-1);
}
else
{
for (int i = 0; i <= z; i++)
{
dp[i, 1] = dp[i, 0] = -1;
}
Console.WriteLine(Solve(0, false));
}
}
}
JavaScript
const N = 5 * 10**3 + 15;
// dp table for memoization
const dp = Array.from({ length: N }, () => Array(2).fill(-1));
let n, x, y, z;
let A, B;
// vector to store indices which differ in string A and B
let v = [];
function solve(idx, flag) {
if (idx > z) {
return 1e10;
}
if (idx === z) {
return 0;
}
if (dp[idx][flag] !== -1) {
return dp[idx][flag];
}
let cost = 0;
// If the current index is not the last index of A
if (idx + 1 < z) {
// We cannot change the current index free of cost
if (!flag) {
cost = Math.min(solve(idx + 1, 1) + y, solve(idx + 2, 0) + (v[idx + 1] - v[idx]) * x);
}
// We can change the current index free of cost
else {
cost = Math.min(solve(idx + 1, 0), solve(idx + 2, 1) + (v[idx + 1] - v[idx]) * x);
}
}
// If the current index is the last index of A
else {
// We have to change the current index with some
// previous operation
cost = solve(idx + 1, 0);
}
dp[idx][flag] = cost;
return cost;
}
A = "10000011000001";
B = "00000000000000";
x = 8;
y = 9;
n = A.length;
for (let i = 0; i < n; i++) {
if (A[i] !== B[i]) {
v.push(i);
}
}
z = v.length;
// If the number of different indices is odd, then it is
// impossible to convert A to B
if (z % 2) {
console.log(-1);
} else {
for (let i = 0; i <= z; i++) {
dp[i][1] = dp[i][0] = -1;
}
console.log(solve(0, 0));
}
Time Complexity: O(N)
Auxiliary Space: O(N)
Similar Reads
Minimum Bit Flips to convert A to B Given two numbers A and B. Write a program to count the number of bits needed to be flipped to convert A to B. Examples: Input: A = 10, B = 20Output: 4Explanation: Binary representation of A is 00001010Binary representation of B is 00010100We need to flip highlighted four bits in A to make it B.Inpu
15+ min read
Minimize cost to convert all array elements to 0 Given two integers X and Y and a binary array arr[] of length N whose first and last element is 1, the task is to minimize the cost to convert all array elements to 0, where X and Y represent the cost of converting a subarray of all 1s to 0s and the cost of converting any element to 0 respectively.
12 min read
Minimum cost to convert a '1' to a given number Given a positive integer 'n'. Starting with 1 find the minimum cost required to convert it to n using the following operations : Multiply the number by 2 with costs aAdd 1 to the number with costs bSubtract 1 from the number with costs c.Examples: Input: n = 31, a = 2, b = 5, c = 3Output: 13Explanat
10 min read
Minimum cost to convert str1 to str2 with the given operations Given two strings of equal lengths str1 and str2 consist of characters 'a' and 'b' only. The following operations can be performed on str1: Any character can be changed from 'a' to 'b' or from 'b' to 'a' with 1 unit cost.Any two characters str1[i] and str1[j] can be swapped with cost |i - j|. The ta
6 min read
Minimize cost to traverse the Arrays with given Array switching cost Given three arrays A[], B[] and C[] of size N each and two integers X and Y, the task is to, find the minimum cost to reach the end of the arrays with the following conditions: Select one of the three elements at every index. For switching from 1st array to 2nd or vice versa, extra X points are requ
8 min read
Minimize the cost to convert given string to either type XYXY... or XXYY... Given a binary string s and an array ct[] of even size. The task is to minimize the cost of operations to: Convert string s to a string of either type XYXYXYXYXY... or XXYYXXYYXXYY...In one operation it is allowed to flip ith character with cost ct[i]. Examples Input: s = "1011" ct = {1, 2, 1, 3}Out
8 min read