-
Notifications
You must be signed in to change notification settings - Fork 0
/
MinimumCostToMerge.cpp
77 lines (60 loc) · 2.63 KB
/
MinimumCostToMerge.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include<bits/stdc++.h>
using namespace std;
class Solution {
public:
int dp[50][50][50];
int minCost(int i,int j,int piles,vector<int>&prefixsum,int &K){
// Cost of converting segment [i..i] into 1 pile is zero
if( i == j && piles == 1)
return 0;
// Cost of converting segment[i..i] into other than 1 pile is not possible , so placed MAX value
if(i == j)
return INT_MAX/4;
// Check whether the subproblem has already been solved .
if(dp[i][j][piles]!=-1)
return dp[i][j][piles];
// If segment[i...j] is to converted into 1 pile
if(piles == 1){
// Here dp(i,j,1) = dp(i,j,K) + sum[i...j]
return dp[i][j][piles] = minCost(i,j,K,prefixsum,K) + (i==0 ? prefixsum[j] : prefixsum[j]-prefixsum[i-1]);
} else {
// dp(i,j,piles) = min( dp(i,j,piles), dp(i,t,1) + dp(t+1,j,piles-1)) for all t E i<=t<j
int cost = INT_MAX/4;
for(int t=i;t<j;t++){
cost = min(cost, minCost(i,t,1,prefixsum,K) + minCost(t+1,j,piles-1,prefixsum,K));
}
return dp[i][j][piles] = cost;
}
}
int mergeStones(vector<int>& stones, int k) {
// the size of the stones
int n = stones.size();
/*
Check whether we will be able to merge n stones into 1 stone .
In step-1 we merge k stones and then we are left with n-k+1 stones or n-(k-1);
In Step-2 we again merge k stones and then we are left with ((n-k+1)-k)+1 or n-2*(k-1);
In Step-3 we gain merge k stones and left with (((n-k+1)-k+1)-k)+1 or n-3*(k-1)
.......
.......
.......
After some m steps we should be left with 1 stones
Therefore , n-m*(k-1) == 1
(n-1)-m*(k-1)=0;
Since m needs to be an integer therefore ,
if (n-1)%(k-1) == 0 ,
then we can merge otherwise not possible.
*/
if((n-1)%(k-1)!=0)
return -1;
int sum = 0;
vector<int>prefixsum;
// Calculating the prefix sum so that sum of any segment[i..j] can be calculated easily
for(int i=0;i<stones.size();i++){
sum+=stones[i];
prefixsum.push_back(sum);
}
memset(dp,-1,sizeof(dp));
// find the minimum cost to merge stones[0...n-1] into 1 piles
return minCost(0,n-1,1,prefixsum,k);
}
};