Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

newly updated #3521

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
code Updated
  • Loading branch information
vikrantvikaasa27 committed Mar 17, 2023
commit bda8fb9740b4fba5d7f9b74d55fa047ebe70560d
62 changes: 13 additions & 49 deletions dynamic_programing/Python/Merge Elements/mergeElements.py
Original file line number Diff line number Diff line change
@@ -1,54 +1,18 @@
"""
Description
def mergeElements(arr):
n = len(arr)
dp = [[0 for _ in range(n)] for _ in range(n)]

You are given N elements, in an array A. You can take any 2 consecutive elements a and b and merge them. On merging you get a single element with value (a+b)%100 and this process costs you a*b. After merging you will place this element in place of those 2 elements.


If the sequence is [A1, A2, A3, A4] and you merge A2 and A3, you incur a cost of A2*A3 and the array becomes [A1, (A2+A3)%100, A4].


Find the Minimum cost to merge all the elements into a single element.
"""


def mergeElements(l, r):
if l == r:
return 0

if dp[l][r] == -1:
total = 0
for i in range(l, r + 1):
total += arr[i]

summ = 0
for mid in range(l, r):
summ += arr[mid]
ans = min(
ans,
mergeElements(l, mid)
+ mergeElements(mid + 1, r)
+ (summ) * (total - summ),
)

dp[l][r] = ans
return dp[l][r]
# Fill in the dp table diagonally
for gap in range(1, n):
for l in range(n - gap):
r = l + gap
total = sum(arr[l:r+1])
dp[l][r] = float('inf')
for mid in range(l, r):
dp[l][r] = min(dp[l][r], dp[l][mid] + dp[mid+1][r] + total)

return dp[0][n-1]

n = int(input())
arr = [int(x) for x in input().split()]
dp = [[-1 for i in range(4001)] for j in range(4001)]
print(mergeElements(0, n - 1))


"""
The nice observation here is the value of the Final element remains fixed and is the sum of the range %100.

So we can design a DP with the states
DP(l,r) = minimum cost to merge the segment into one element.

Now range (l,r) will form one element from 2 elements in the final step.
So let's say the (l, mid) and (mid+1,r) range equivalents merge and produce the final element.

So DP(l,r) = min(DP(l,mid) + DP(mid+1,r) + (sum(l,mid)%100)*(sum(mid+1,r)%100) ) for all mid in range [l,r).

"""
print(mergeElements(arr))