# Maximum Product Cutting

Maximum Product Cutting: Given a rope of length n meters, cut the rope in different parts of integer lengths in a way that maximizes product of lengths of all parts.
Submitted by Divyansh Jaipuriyar, on August 31, 2020

Problem statement:

Given a rope of length n meters, cut the rope in different parts of integer lengths in a way that maximizes the product of lengths of all parts. You must make at least one cut. Assume that the length of the rope is more than 2 meters.

Problem description:

The problem wants you to find the maximum value of the product that you can obtain making certain partition at some points on the rope, you can make a partition between rope if the length of the rope is greater than 1 and the partitioned length can again be partitioned into some segments unless you get the maximum value of the product.i.e n->(1 and (n-1), then (n-1) can be partitioned into more segments such as (n-3) and (2) since (n-3)+2==(n-1). You are allowed to make any number of partitions according to your choice but they should return the maximum value.

Input:

The first line of input is T, number of test cases. Each test case consist of N the size of rope.

Output:

Output the maximum product of all cutting that you made.

Examples:

```Input:
T=3
10
5
8

Output:
36
6
18
```

Solution Approach:

(a) Recursion Approach:

In this approach we will use recursion to solve, we will create a solve function that will take the size of the rope as its parameter.

The base case for the solve function will be n==0 or n==1 since in this case, we can't make any cut.

For any other length of rope we have following option:

solve(n)=max(i*(n-i),solve(n-i)*i) for all i from 1,2,3,4......n-1, and here n>=2 in size.

For n==0 and for n==1 we simply return 0 as there is no further partition.

In the recursive function, we declare some temporary variable res which will be initialized with minimum value as we iterate through the entire length from (i>=1 to i<n) and check for each partition and then return the maximum value.

Time complexity for the above approach in the worst case is exponential
Space complexity for the above approach in the worst case is: O(1)

(b) Dynamic Programming Approach:

(i) Top Down Approach:

In this approach we will use the recursion plus memorization technique, we will create a dp[n] state which will store the value of the calculated value of maximum product cutting for length n.

We initially fill all the value of dp[i] state with -1, then we calculate then we assign dp[n] if not calculated already otherwise we will directly return the value for dp[n] without recalculating it again.

Time complexity for this approach in the worst case is: O(n*n)

Space complexity for this approach in the worst case is: O(n)

(ii) Bottom Approach:

In this approach of Dp we will create the dp[] array of size n+1 because of 0 based indexing. We will fill the dp[] state in a bottom-up manner.

The base case here will be for length 0 and 1 as 0.

dp=dp=0

And for other lengths of the rope, we will check the maximum value that we can obtain before making a partition from length (1 to current length -1), that's why the inner loop iterate through 1 to i (outer loop variable).

i.e(j>=1 to j<=(i-1))

Time complexity for the above approach in the worst case is: O(n*n)

Space complexity for the above approach in the worst case: O(n)

C++ Implementation (Recursion Approach):

```#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

//solve function for computation.
ll solve(ll n)
{
//base cases of n==0 and n==1.
if (n == 1 || n <= 0)
return 0;

//initialize variable res as min
//so that on further operation it
//can check for large values
ll res = INT_MIN;

//iterate through different length
//where we make cut.
for (ll i = 1; i < n; i++) {
//check for other cases.
res = max(max(res, i * (n - i)), i * solve(n - i));
}
//return res.
return res;
}

int main()
{
ll t;
cout << "Enter number of test cases: ";
cin >> t;

while (t--) {
cout << "Enter size of rope: ";
ll n;
cin >> n;

cout << "Maximum product cutting: ";

cout << solve(n) << "\n";
}

return 0;
}
```

Output:

```Enter number of test cases: 3
Enter size of rope: 10
Maximum product cutting: 36
Enter size of rope: 5
Maximum product cutting: 6
Enter size of rope: 8
Maximum product cutting: 18
```

C++ Implementation (Top-Down Dynamic Programming Approach):

```#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

//initialize dp state.
ll dp;

//solve function for computation.
ll solve(ll n)
{
//base cases of n==0 and n==1.
if (n == 1 || n <= 0)
return 0;

if (dp[n] != -1)
return dp[n];

//initialize variable res as min
//so that on further operation it
//can check for large values
ll res = INT_MIN;

//iterate through different length
//where we make cut.
for (ll i = 1; i < n; i++) {
res = max(max(res, i * (n - i)), i * solve(n - i));
}
//store result and return result.
return dp[n] = res;
}

int main()
{
ll t;
cout << "Enter number of test cases: ";
cin >> t;

while (t--) {
cout << "Enter size of rope: ";
ll n;
cin >> n;

//fill dp states with -1.
memset(dp, -1, sizeof(dp));

cout << "Maximum product cutting: ";
cout << solve(n) << "\n";
}

return 0;
}
```

Output:

```Enter number of test cases: 3
Enter size of rope: 12
Maximum product cutting: 81
Enter size of rope: 100
Maximum product cutting: 7412080755407364
Enter size of rope: 15
Maximum product cutting: 243
```

C++ Implementation (Bottom-Up Dynamic Programming Approach):

```#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

//declare solve function.
ll solve(ll n)
{
//declare dp state of length n+1.
ll dp[n + 1];

//initialize base cases.
dp = dp = 0;

//iterate through different
//size of rope length.
for (ll i = 1; i <= n; i++) {

ll res = INT_MIN;
//iterate through cuts
for (ll j = 1; j < i; j++)
res = max(max(j * (i - j), j * dp[i - j]), res);
//store res in dp[i] state.
dp[i] = res;
}
//return maximum dp[n] value.
return dp[n];
}

int main()
{
ll t;
cout << "Enter number of test cases: ";
cin >> t;

while (t--) {
cout << "Enter size of rope: ";
ll n;
cin >> n;

cout << "Maximum product cutting: ";
cout << solve(n) << "\n";
}

return 0;
}
```

Output:

```Enter number of test cases: 3
Enter size of rope: 10
Maximum product cutting: 36
Enter size of rope: 2
Maximum product cutting: 1
Enter size of rope: 5
Maximum product cutting: 6
```