// C# implementation of the approach
using System;
using System.Collections.Generic;
class GFG
{
readonly static int MAX = 1001;
// dp[i,j] will store the minimum cost
// of partitioning the string into j
// parts starting at the ith index
static int [,]dp = new int [MAX, MAX];
// Recursive function to find
// the minimum cost required
static int minCost(String s, int k, int cost, int i, int n)
{
int count_0 = 0;
// If the state has been solved before
if (dp[i, k] != -1)
return dp[i, k];
// If only 1 part is left then the
// remaining part of the string will
// be considered as that part
if (k == 1)
{
// To store the count of 0s and the
// total characters of the string
int total = n - i;
// Count the 0s
while (i < n)
if (s[i++] == '0')
count_0++;
// Memoize and return the updated cost
dp[i, k] = cost + (count_0
* (total - count_0));
return dp[i, k];
}
int curr_cost = int.MaxValue;
count_0 = 0;
// Check all the positions to
// make the current partition
for (int j = i; j < n - k + 1; j++)
{
// Count the numbers of 0s
if (s[j] == '0')
count_0++;
int curr_partlength = j - i + 1;
// Cost of partition is equal to
// (no. of 0s) * (no. of 1s)
int part_cost = (count_0
* (curr_partlength - count_0));
// string, partitions, curr cost,
// start index,.Length
part_cost += minCost(s, k - 1, 0, j + 1, n);
// Update the current cost
curr_cost = Math.Min(curr_cost, part_cost);
}
// Memoize and return the updated cost
dp[i, k] = (cost + curr_cost);
return (cost + curr_cost);
}
// Driver code
public static void Main (String[] args)
{
String s = "110101";
int n = s.Length;
int k = 3;
// Initialise the dp array
for (int i = 0; i < MAX; i++)
{
for (int j = 0; j < MAX; j++)
dp[i, j] = -1;
}
// string, partitions, curr cost,
// start index,.Length
Console.WriteLine(minCost(s, k, 0, 0, n));
}
}
// This code is contributed by 29AjayKumar