- Data Structure
- Networking
- RDBMS
- Operating System
- Java
- MS Excel
- iOS
- HTML
- CSS
- Android
- Python
- C Programming
- C++
- C#
- MongoDB
- MySQL
- Javascript
- PHP
- Physics
- Chemistry
- Biology
- Mathematics
- English
- Economics
- Psychology
- Social Studies
- Fashion Studies
- Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Minimum sum of multiplications of n numbers
In this article, we will discuss two approaches to generate the desired sum. Both the approaches are dynamic programming-based approaches. In the first approach, we will memorization for dynamic programming and then we will apply the same approach for tabulation in order to avoid the use of extra stack space for recursion.
Problem Statement
We are given a list of n integers, and our goal is to minimize the sum of multiplications by repeatedly taking two adjacent numbers, summing them modulo 100, and replacing them in the list until only one number remains.
Let's consider the input [30, 40, 50] and calculate the minimum sum of multiplications.
To find the minimum sum, we'll explore different possibilities −
Case 1 − Take 30 and 40
Multiplication: 30 * 40 = 1200
And put back (30 + 40)%100= 70
After performing the operation, the list becomes: 70, 50
Multiplication Sum: 1200 + (70 * 50) = 4700
Case 2 − Take 40 and 50
Multiplication: 40 * 50 = 2000
And put back (40 + 50)%100 = 90
After performing the operation, the list becomes: 30, 90
Multiplication Sum: 2000 + (30 * 90) = 4700
Comparing the two cases, we see that the minimum sum of multiplications is 2000, which occurs in Case 2.
Therefore, the output is: 2000.
Approach 1
One approach is to solve this problem recursively, we can break it down into smaller parts and combine the results to find the optimal solution. We can define a 2D table, DP[iterator1][iterator2], where iterator1 and iterator2 represent the indices of the numbers in the range we are considering. The DP table will store the minimum sum of multiplications for multiplying the numbers from iterator1 to iterator2.
We will firstly apply memoization to this approach in order to neglect the overlapping subproblems.
Example
The dynamic programming approach to the problem is given below −
#include <bits/stdc++.h> using namespace std; long long DP[1000][1000]; long long mult_sum( int nums[], int iterator, int iterator2){ long long sol = 0; for ( int i = iterator; i <= iterator2; i++ ){ sol = (sol + nums[i]) % 100; } return sol; } long long solve(int nums[], int iterator, int iterator2){ if (iterator == iterator2) return 0; if (DP[iterator][iterator2] != -1) return DP[iterator][iterator2]; DP[iterator][iterator2] = INT_MAX; for (int k = iterator; k < iterator2; k++){ DP[iterator][iterator2] = min(DP[iterator][iterator2], (solve(nums, iterator, k) + solve(nums, k + 1, iterator2) + (mult_sum(nums, iterator, k) * mult_sum(nums, k + 1, iterator2)))); } return DP[iterator][iterator2]; } int main() { int nums[] = { 30, 40, 50 }; int n = sizeof(nums)/sizeof(nums[0]); for (int iterator = 0; iterator <= n ; iterator++) for (int iterator2 = 0; iterator2 <= n ; iterator2++) DP[iterator][iterator2] = -1; cout << "The sum of multiplication of the numbers according to the definition given in the problem is " << solve(nums, 0, n - 1) << endl; return 0; }
Output
The sum of multiplication of the numbers according to the definition given in the problem is 4700
Approach 2
As we know, the memorization approach of dynamic programming needs an extra stack space for its execution, hence to reduce this space complexity, we can apply the same approach is top down manner i.e., tabulation method.
Example
The tabulation approach for the same problem discussed above is −
#include <bits/stdc++.h> using namespace std; long long mult_sum(int nums[], int iterator, int iterator2){ long long sol = 0; for (int it = iterator; it <= iterator2; it++){ sol = (sol + nums[it]) % 100; } return sol; } long long min_sum_mult(int nums[], int n){ long long store_dp[n][n]; for (int iterator1 = 0; iterator1 < n; iterator1++) { for (int iterator2 = 0; iterator2 < n; iterator2++) { store_dp[iterator1][iterator2] = 0; } } for (int iterator1 = 2; iterator1 <= n; iterator1++) { for (int iterator2 = 0; iterator2 < n - iterator1 + 1; iterator2++) { int j = iterator2 + iterator1 - 1; store_dp[iterator2][j] = INT_MAX; for (int iterator3 = iterator2; iterator3 < j; iterator3++) { store_dp[iterator2][j] = min(store_dp[iterator2][j], (store_dp[iterator2][iterator3] + store_dp[iterator3 + 1][j] + (mult_sum(nums, iterator2, iterator3) * mult_sum(nums, iterator3 + 1, j)))); } } } return store_dp[0][n - 1]; } int main(){ int nums[] = { 30, 40, 50 }; int n = sizeof(nums)/sizeof(nums[0]); cout <<"The sum of multiplication of the numbers according to the definition given in the problem is "<< min_sum_mult(nums, n) << endl; return 0; }
Output
The sum of multiplication of the numbers according to the definition given in the problem is 4700