0

We have an array of "n" numbers. We need to divide it in M subarray such that the cost is minimum.

Cost = (XOR of subarray) X ( length of subarray )

Eg:

array = [11,11,11,24,26,100] 

M = 3

OUTPUT => 119

Explanation:

 Dividing into subarrays as = > [11] , [11,11,24,26] , [100]

As 11*1 + (11^11^24^26)*4 + 100*1 => 119 is minimum value.

Eg2: array = [12,12]
     M = 1

output: 0

As [12,12] one way and (12^12)*2 = 0. 
learner-coder
  • 307
  • 1
  • 10
  • 1
    Ok, what is your attempt so far? – SomeDude Aug 10 '19 at 18:47
  • What is the time complexity you're going for / size of input? – Primusa Aug 11 '19 at 01:28
  • 1 <= M <= 100 and size of array 1 <= n <= 1000. I am able to proceed in any direction like considering each and every subarray so that lands me to dynamic programming zone. And than i am not able to understand how to procedd. – learner-coder Aug 11 '19 at 02:42

1 Answers1

1

You can solve this problem by using dynamic programming.

Let's define dp[i][j]: the minimum cost for solving this problem when you only have the first i elements of the array and you want to split (partition) them into j subarrays.

dp[i][j] = cost of the last subarray plus cost of the partitioning of the other part of the given array into j-1 subarrays

This is my solution which runs in O(m * n^2):

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1000 + 10;
const int MAXM = 1000 + 10;
const long long INF = 1e18 + 10;

int n, m, a[MAXN];
long long dp[MAXN][MAXM];

int main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    // start of initialization
    for (int i = 0; i <= n; i++)
        for (int j = 0; j <= n; j++)
            dp[i][j] = INF;
    dp[0][0] = 0;
    // end of initialization
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            int last_subarray_xor = 0, last_subarray_length = 0;
            for (int k = i; k >= 1; k--) {
                last_subarray_xor ^= a[k];
                last_subarray_length = i - k + 1;
                dp[i][j] = min(dp[i][j], dp[k - 1][j - 1] + (long long)last_subarray_xor * (long long)last_subarray_length);
            }
        }
    }
    cout << dp[n][m] << endl;
    return 0;
}

Sample input:

6 3
11 11 11 24 26 100

Sample output:

119

One of the most simple classic dynamic programming problems is called "0-1 Knapsack" that's available on Wikipedia.