给定n个整数。任务是通过一次取两个相邻的数字并将它们的和%放回100,直到剩下一个数字,来最小化所有数字的乘积和。
例子 :
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
方法:问题是矩阵链乘法动态规划的一种变体
想法是将N个数划分为k的每个可能值。递归求解较小的部分,然后相乘并存储最小值。由于我们将其划分为k个部分,因此对于每个DP i,j,我们将有k个分区i <= k DPi,j = min(DPi,j , (DPi,k+DPk+1,j+(cumulative_sumi,k*cumulative_sumk+1,j) ) ) 由于将重复许多子问题,因此我们使用备忘录将值存储在nXn矩阵中。 下面给出了上述方法的说明: 输出 : 时间复杂度: O(n ^ 3)
for every i<=kC++
// CPP program to find the
// minimum sum of multiplication
// of n numbers
#include
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 intialize(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;
intialize(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 intialize(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)
intialize(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 intialize(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;
intialize(n);
Console.WriteLine(solve(a, 0, n - 1));
}
}
// This code is contributed by vt_m.
PHP
2400
辅助空间: O(n ^ 2)