# Solution For Minimum Cost To Merge Stones

The Minimum Cost to Merge Stones problem is a dynamic programming problem on LeetCode. The problem statement is as follows:

You have a list of N stones, where each stone has a certain value. You want to merge the stones together into one pile, but you can only merge adjacent stones. The cost of merging two stones is the sum of their values. Find the minimum cost of merging all the stones into one pile.

To solve this problem, we can use a bottom-up dynamic programming approach. We can define a two-dimensional array dp, where dp[i][j] represents the minimum cost of merging stones i to j into one pile. The base case is when i = j, in which case the cost is 0.

We can then compute the values of dp[i][j] using the following recurrence relation:

dp[i][j] = min(dp[i][k] + dp[k+1][j] + sum(a[i..j])), i <= k < j

Here, sum(a[i..j]) represents the sum of values of stones i to j, inclusive. The recurrence relation essentially says that we consider all possible ways of splitting the stones into two sub-piles, merge each sub-pile recursively, and then merge the two resulting piles together at a cost equal to the sum of values of the stones in each pile.

We can compute the values of dp in increasing order of sub-pile sizes. Specifically, we can iterate over all possible sub-pile sizes L, and for each sub-pile size, iterate over all possible starting indices i for sub-piles of that size. For each starting index i, we can compute the corresponding ending index j and then compute the value of dp[i][j] using the recurrence relation.

Finally, the minimum cost of merging all the stones into one pile is given by dp[N]. The time complexity of this approach is O(N^3), since there are N^2 possible sub-piles and each sub-pile requires O(N) time to process.

Here’s the Python code to implement this approach:

def mergeStones(stones):
N = len(stones)
dp = [ * (N+1) for _ in range(N+1)] for L in range(2, N+1):
for i in range(1, N-L+2):
j = i + L – 1
dp[i][j] = float(‘inf’)
for k in range(i, j):
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j] + sum(stones[i-1:j]))
return dp[N] if dp[N] != float(‘inf’) else -1

Note that we initialize dp[i][j] to float(‘inf’) to indicate that the value has not yet been computed. We also check if dp[N] is equal to float(‘inf’) after computing all the values, since this indicates that it was not possible to merge all the stones into one pile.

## Step by Step Implementation For Minimum Cost To Merge Stones

```There is a stone pile with n stones. Each stone has a positive integer weight.

In each move, we can merge two adjacent stones into one stone with weight of their sum. The cost of this move is the sum of the weights of the stones merged. We merge the stones until there is only 1 stone left.

Return the minimum cost it takes to merge all the stones into 1 stone. If it is impossible to merge all the stones into 1 stone, return -1.

// n is the number of stones
// w is the array of stone weights

public int minimumCostToMergeStones(int n, int[] w) {
// dp[i][j] is the minimum cost to merge stones from i to j into 1 stone
int[][] dp = new int[n][n];
// prefixSum[i] is the sum of stone weights from 0 to i
int[] prefixSum = new int[n];

// calculate prefix sums
for (int i = 0; i < n; i++) {
prefixSum[i] = w[i];
if (i > 0) {
prefixSum[i] += prefixSum[i - 1];
}
}

// base case: dp[i][i] = 0 for all i
// calculate dp for subproblems of increasing size
for (int size = 2; size <= n; size++) {
for (int i = 0; i <= n - size; i++) {
int j = i + size - 1;
dp[i][j] = Integer.MAX_VALUE;
// try merging stones from i to k, then k+1 to j
for (int k = i; k < j; k++) {
dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k+1][j]);
}
// if all stones from i to j can be merged into 1 stone,
// update dp[i][j] with the cost of this merge
if ((size == n - 1) && ((prefixSum[j] - prefixSum[i] + w[i]) % n == 0)) {
dp[i][j] = dp[i][j] + (prefixSum[j] - prefixSum[i] + w[i]) / n;
}
}
}
// return the minimum cost to merge all stones into 1 stone, or -1 if it's impossible
return (dp[n-1] == Integer.MAX_VALUE) ? -1 : dp[n-1];
}```
```There are a number of ways to solve this problem. One approach would be to use a priority queue to keep track of the costs of merging the stones. We would then repeatedly merge the two cheapest stones until there is only one stone left. The cost of merging two stones is the sum of the sizes of the stones.

import heapq

def merge_stones(stones):
# create a priority queue to store the stones
pq = []
for stone in stones:
heapq.heappush(pq, stone)

# keep track of the cost of merging the stones
cost = 0

# repeatedly merge the two cheapest stones until there is only one stone left
while len(pq) > 1:
# get the two cheapest stones
stone1 = heapq.heappop(pq)
stone2 = heapq.heappop(pq)

# merge the two stones and add the cost to the total
cost += stone1 + stone2

# add the merged stone back into the priority queue
heapq.heappush(pq, stone1 + stone2)

return cost```
```There are a number of stones arranged in a row.  The i-th stone has a weight of stones[i].

Each turn, we pick up two adjacent stones and smash them together.  Suppose the stones have weights x and y with x <= y.  The result of this smash is:

If x == y, both stones are totally destroyed;
If x != y, the stone of weight x is totally destroyed, and the stone of weight y has new weight y-x.
At the end, there is at most 1 stone left.  Return the smallest possible weight of this stone (the weight is 0 if there are no stones left.)

function mergeStones(stones) {
// base case: if there's only one stone left, return its weight
if (stones.length === 1) {
return stones;
}

// sort the stones from smallest to largest
stones.sort((a, b) => a - b);

// initialize a variable to keep track of the minimum cost
let minCost = Infinity;

// loop through all of the stones
for (let i = 0; i < stones.length - 1; i++) {
// initialize a variable to keep track of the current cost
let cost = 0;

// get the weight of the current stone
let stone = stones[i];

// loop through all of the stones that come after the current stone
for (let j = i + 1; j < stones.length; j++) {
// get the weight of the next stone
let nextStone = stones[j];

// if the weights of the stones are equal, both stones are destroyed
if (stone === nextStone) {
// remove the stones from the array
stones.splice(i, 2);
// reset the indices so we don't skip any stones
i = -1;
j = 0;
} else {
// otherwise, the stone of weight x is destroyed and the stone of weight y has new weight y-x
stone = nextStone - stone;
// remove the first stone from the array
stones.splice(i, 1);
// add the new stone to the array
stones.splice(j, 0, stone);
// reset the indices so we don't skip any stones
i = -1;
j = 0;
}

// add the cost of the current operation to the total cost
cost += stone;
}

// update the minimum cost if necessary
minCost = Math.min(minCost, cost);
}

// return the minimum cost
return minCost;
}```
```There are a number of ways to solve this problem. One approach would be to use a priority queue to store the stones in order of increasing cost. Then, we can repeatedly remove the two cheapest stones and merge them together, keeping track of the total cost. Finally, we can return the cost of the merged stone.

#include
#include

int mergeStones(std::vector& stones) {
// create a priority queue to store the stones
std::priority_queue, std::greater> pq(stones.begin(), stones.end());

// keep track of the total cost
int cost = 0;

// while there are more than 1 stone remaining
while (pq.size() > 1) {
// remove the two cheapest stones
int stone1 = pq.top();
pq.pop();
int stone2 = pq.top();
pq.pop();

// merge the stones and add the cost to the total
int mergedStone = stone1 + stone2;
cost += mergedStone;

// add the merged stone back into the priority queue
pq.push(mergedStone);
}

// return the cost
return cost;
}```
```There are a number of stones arranged in a row. Each stone has a weight associated with it. You would like to merge the stones into one stone by repeated merging of the stones. In each merge operation, you select any 2 stones that have the same weight, and merge them into a new stone that has the weight of the sum of the 2 stones' weights. The new stone is then placed back in the row.

You would like to find the minimum cost of merging all of the stones into a single stone. The cost of merging 2 stones is the sum of their weights.

class Solution { public int MergeStones(int[] stones, int K) { // TODO: Implement solution } }```

Scroll to Top

## Top 100 Leetcode Practice Problems In Java

Get 30% Off Instantly!
[gravityforms id="5" description="false" titla="false" ajax="true"]