Suma mínima de multiplicaciones de n números

Dados n enteros. La tarea es minimizar la suma de la multiplicación de todos los números tomando dos números adyacentes a la vez y devolviendo su suma % 100 hasta que quede un número. 

Ejemplos: 

Input : 40 60 20 
Output : 2400  
Explanation: There are two possible cases:
1st possibility: Take 40 and 60, so multiplication=2400
and put back (60+40) % 100 = 0, making it 0, 20.
Multiplying 0 and 20 we get 0 so 
multiplication = 2400+0 = 2400. Put back (0+20)%100 = 20. 
2nd possibility: take 60 and 20, so 60*20 = 1200,
put back (60+20)%100 = 80, making it [40, 80] 
multiply 40*80 to get 3200, so multiplication
sum = 1200+3200 = 4400. Put back (40+80)%100 = 20 

Input : 5 6 
Output : 30 
Explanation: Only possibility is 5*6=30 

Enfoque: El problema es una variación de la array en string Multiplicación Programación dinámica
La idea es dividir N números en todos los valores posibles de k. Resuelva recursivamente para partes más pequeñas y agregue la multiplicación y almacene el mínimo de ellas. Como lo estamos dividiendo en k partes, para cada DP i,j tendremos k particiones i<=k<j , almacene el mínimo de ellas. Entonces obtenemos la fórmula similar a la Programación dinámica de multiplicación de string matricial

DP i,j = min(DP i,j , (DP i,k +DP k+1,j +(cumulative_sum i,k *cumulative_sum k+1,j ) ) ) 
para cada i<=k<j. 

Dado que muchos subproblemas se repetirán, usamos la memorización para almacenar los valores en una array nXn. 

A continuación se muestra la ilustración del enfoque anterior:  

C++

// CPP program to find the
// minimum sum of multiplication
// of n numbers
#include <bits/stdc++.h>
using namespace std;
 
// Used in recursive
// memoized solution
long long dp[1000][1000];
 
// function to calculate the cumulative
// sum from a[i] to a[j]
long long sum(int a[], int i, int j)
{    
    long long ans = 0;
    for (int m = i; m <= j; m++)    
        ans = (ans + a[m]) % 100;
    return ans;
}
 
long long solve(int a[], int i, int j)
{
    // base case
    if (i == j)
        return 0;
     
    // memoization, if the partition
    // has been called before then
    // return the stored value
    if (dp[i][j] != -1)
        return dp[i][j];
     
    // store a max value
    dp[i][j] = INT_MAX;
     
    // we break them into k partitions
    for (int k = i; k < j; k++)
    {
        // store the min of the
        // formula thus obtained
        dp[i][j] = min(dp[i][j], (solve(a, i, k) +
                              solve(a, k + 1, j) +
              (sum(a, i, k) * sum(a, k + 1, j))));
    }
     
    // return the minimum
    return dp[i][j];
}
 
void initialize(int n)
{
    for (int i = 0; i <= n; i++)
        for (int j = 0; j <= n; j++)
            dp[i][j] = -1;    
}
 
// Driver code
int main() {
    int a[] = {40, 60, 20};
    int n = sizeof(a) / sizeof(a[0]);
    initialize(n);
    cout << solve(a, 0, n - 1) << endl;
    return 0;
}

Java

// Java program to find the 
// minimum sum of multiplication
// of n numbers
import java.io.*;
import java.math.*;
 
 
class GFG
{
     
    // Used in recursive
    // memoized solution
    static long dp[][] = new long[1000][1000];
     
    // function to calculate the
    // cumulative  sum from a[i] to a[j]
    static long sum(int a[], int i, int j)
    {    
        long ans = 0;
        for (int m = i; m <= j; m++)    
            ans = (ans + a[m]) % 100;
        return ans;
    }
     
    static long solve(int a[], int i, int j)
    {
        // base case
        if (i == j)
            return 0;
         
        // memoization, if the partition
        // has been called before then
        // return the stored value
        if (dp[i][j] != -1)
            return dp[i][j];
         
        // store a max value
        dp[i][j] = 100000000;
         
        // we break them into k partitions
        for (int k = i; k < j; k++)
        {
            // store the min of the
            // formula thus obtained
            dp[i][j] = Math.min(dp[i][j], (solve(a, i, k) +
                                       solve(a, k + 1, j) +
                        (sum(a, i, k) * sum(a, k + 1,j))));
        }
         
        // return the minimum
        return dp[i][j];
    }
     
    static void initialize(int n)
    {
        for (int i = 0; i <= n; i++)
            for (int j = 0; j <= n; j++)
                dp[i][j] = -1;    
    }
     
    // Driver code
    public static void main(String args[])
    {
        int a[] = {40, 60, 20};
        int n = a.length;
        initialize(n);
        System.out.println(solve(a, 0, n - 1));
         
    }
}
 
/*This code is contributed by Nikita Tiwari.*/

Python3

# Python3 program to find the
# minimum sum of multiplication
# of n numbers
 
import numpy as np
import sys
 
# Used in recursive
# memoized solution
dp = np.zeros((1000,1000))
 
# function to calculate the cumulative
# sum from a[i] to a[j]
def sum(a, i, j) :
         
    ans = 0
    for m in range(i, j + 1) :
        ans = (ans + a[m]) % 100
         
    return ans
 
 
def solve(a, i, j) :
 
    # base case
    if (i == j) :
        return 0
     
    # memoization, if the partition
    # has been called before then
    # return the stored value
    if (dp[i][j] != -1) :
                 
        return dp[i][j]
     
    # store a max value
    dp[i][j] = sys.maxsize
     
    # we break them into k partitions
    for k in range(i, j) :
                 
        # store the min of the
        # formula thus obtained
        dp[i][j] = min(dp[i][j], (solve(a, i, k) + solve(a, k + 1, j)
                                + (sum(a, i, k) * sum(a, k + 1, j))))
     
    # return the minimum
    return dp[i][j]
 
 
def initialize(n) :
         
    for i in range(n + 1) :
        for j in range(n + 1) :
            dp[i][j] = -1   
 
#Driver code
if __name__ == "__main__" :
         
    a = [40, 60, 20]
    n = len(a)
    initialize(n)
    print(int(solve(a, 0, n - 1)))
 
# This code is contributed by Ryuga

C#

// C# program to find the
// minimum sum of multiplication
// of n numbers
using System;
 
class GFG
{
     
    // Used in recursive
    // memoized solution
    static long [,]dp = new long[1000, 1000];
     
    // Function to calculate the cumulative
    // sum from a[i] to a[j]
    static long sum(int []a, int i, int j)
    {
        long ans = 0;
        for (int m = i; m <= j; m++)
            ans = (ans + a[m]) % 100;
        return ans;
    }
     
    static long solve(int []a, int i, int j)
    {
        // base case
        if (i == j)
            return 0;
         
        // memoization, if the partition
        // has been called before then
        // return the stored value
        if (dp[i, j] != -1)
            return dp[i, j];
         
        // store a max value
        dp[i, j] = 100000000;
         
        // we break them into k partitions
        for (int k = i; k < j; k++)
        {
            // store the min of the
            // formula thus obtained
            dp[i, j] = Math.Min(dp[i, j], (solve(a, i, k) +
                                       solve(a, k + 1, j) +
                       (sum(a, i, k) * sum(a, k + 1, j))));
        }
         
        // return the minimum
        return dp[i, j];
    }
     
    static void initialize(int n)
    {
        for (int i = 0; i <= n; i++)
            for (int j = 0; j <= n; j++)
                dp[i, j] = -1;
    }
     
    // Driver code
    public static void Main()
    {
        int []a = {40, 60, 20};
        int n = a.Length;
        initialize(n);
        Console.WriteLine(solve(a, 0, n - 1));
         
    }
}
 
// This code is contributed by vt_m.

PHP

<?php
// PHP program to find the
// minimum sum of multiplication
// of n numbers
 
 
// Used in recursive
// memoized solution
$dp = array(array());
 
// function to calculate the
// cumulative sum from a[i] to a[j]
function sum( $a, $i, $j)
{
    $ans = 0;
    for ( $m = $i; $m <= $j; $m++)
        $ans = ($ans + $a[$m]) % 100;
    return $ans;
}
 
function solve( $a, $i, $j)
{
    global $dp;
    // base case
    if ($i == $j)
        return 0;
     
    // memoization, if the partition
    // has been  called before then
    // return the stored value
    if ($dp[$i][$j] != -1)
        return $dp[$i][$j];
     
    // store a max value
    $dp[$i][$j] = PHP_INT_MAX;
     
    // we break them into
    // k partitions
    for ( $k = $i; $k < $j; $k++)
    {
        // store the min of the
        // formula thus obtained
        $dp[$i][$j] = min($dp[$i][$j],
                      (solve($a, $i, $k) +
                       solve($a, $k + 1, $j) +
                      (sum($a, $i, $k) *
                       sum($a, $k + 1, $j))));
    }
     
    // return the minimum
    return $dp[$i][$j];
}
 
function initialize( $n)
{
    global $dp;
    for ( $i = 0; $i <= $n; $i++)
        for ( $j = 0; $j <= $n; $j++)
            $dp[$i][$j] = -1;
}
 
// Driver code
$a = array(40, 60, 20);
$n = count($a);
initialize($n);
echo solve($a, 0, $n - 1) ;
 
// This code is contributed by anuj_67.
?>

Javascript

<script>
 
// JavaScript program to find the
// minimum sum of multiplication
// of n numbers
 
// Used in recursive
// memoized solution
var dp = Array.from(Array(1000), ()=>Array(1000));
 
// function to calculate the cumulative
// sum from a[i] to a[j]
function sum( a,  i,  j)
{    
    var ans = 0;
    for (var m = i; m <= j; m++)    
        ans = (ans + a[m]) % 100;
    return ans;
}
 
function solve( a,  i,  j)
{
    // base case
    if (i == j)
        return 0;
     
    // memoization, if the partition
    // has been called before then
    // return the stored value
    if (dp[i][j] != -1)
        return dp[i][j];
     
    // store a max value
    dp[i][j] = 1000000000;
     
    // we break them into k partitions
    for (var k = i; k < j; k++)
    {
        // store the min of the
        // formula thus obtained
        dp[i][j] = Math.min(dp[i][j], (solve(a, i, k) +
                              solve(a, k + 1, j) +
              (sum(a, i, k) * sum(a, k + 1, j))));
    }
     
    // return the minimum
    return dp[i][j];
}
 
function initialize(n)
{
    for (var i = 0; i <= n; i++)
        for (var j = 0; j <= n; j++)
            dp[i][j] = -1;    
}
 
// Driver code
var a = [40, 60, 20];
var n = a.length;
initialize(n);
document.write( solve(a, 0, n - 1));
 
</script>

Producción: 

2400

Complejidad de tiempo: O(n^3) 
Espacio auxiliar: O(n^2) 
 

Publicación traducida automáticamente

Artículo escrito por Striver y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *