Editorial
Let represent the minimum cost to reduce the subarray to a single element. This value will be stored in the cell .
Obviously, .
From the problem statement, it follows that
Now, let’s compute . Reducing three numbers into one can be done in two ways:
Merge and with a cost of , then merge and at a cost of .
Merge and with a cost of , then merge and at a cost of .
Thus
Now, let’s consider calculating the value of . To reduce the subarray to a single element equal to , we need to choose some value . Then, recursively solve the problem for the subarrays and , and finally merge the elements and . The value of should be chosen in such a way that the total transformation cost is minimized:
For efficient computation of sums use a prefix sum array , where
so that .
Algorithm implementation
Let’s declare constants and arrays.
#define MAX 101 #define INF 0x3F3F3F3F int dp[MAX][MAX], a[MAX], pref[MAX];
The function returns the minimum cost to transform the subarray into a single element.
int f(int i, int j) { if (dp[i][j] == INF) for (int p = i; p < j; p++) dp[i][j] = min(dp[i][j], f(i, p) + f(p + 1, j) + (pref[j] - pref[i - 1]) * k); return dp[i][j]; }
The main part of the program. Read the input data.
scanf("%d %d", &n, &k); memset(dp, 0x3F, sizeof(dp)); for (i = 1; i <= n; i++) { scanf("%d", &a[i]); dp[i][i] = 0;
Compute the array of prefix sums.
pref[i] = pref[i - 1] + a[i]; }
Compute and print the answer.
printf("%d\n", f(1, n));
Python implementation
Let’s declare the constant for infinity.
INF = float('inf')
The function returns the minimum cost to transform the subarray into a single element.
def f(i, j): if dp[i][j] == INF: for p in range(i, j): dp[i][j] = min(dp[i][j], f(i, p) + f(p + 1, j) + (pref[j] - pref[i - 1]) * k) return dp[i][j]
The main part of the program. Read the input data.
n, k = map(int, input().split()) a = [0] + list(map(int, input().split()))
Compute the array of prefix sums.
pref = [0] * (n + 1) for i in range(1, n + 1): pref[i] = pref[i - 1] + a[i]
Initialize the array.
dp = [[INF] * (n + 1) for _ in range(n + 1)] for i in range(1, n + 1): dp[i][i] = 0
Compute and print the answer.
print(f(1, n))