★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:http://www.javashuo.com/article/p-yhmnfwtj-md.html
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html
There are N
piles of stones arranged in a row. The i
-th pile has stones[i]
stones.git
A move consists of merging exactly K
consecutive piles into one pile, and the cost of this move is equal to the total number of stones in these K
piles.github
Find the minimum cost to merge all piles of stones into one pile. If it is impossible, return -1
.微信
Example 1:app
Input: stones = [3,2,4,1], K = 2 Output: 20 Explanation: We start with [3, 2, 4, 1]. We merge [3, 2] for a cost of 5, and we are left with [5, 4, 1]. We merge [4, 1] for a cost of 5, and we are left with [5, 5]. We merge [5, 5] for a cost of 10, and we are left with [10]. The total cost was 20, and this is the minimum possible.
Example 2:ide
Input: stones = [3,2,4,1], K = 3 Output: -1 Explanation: After any merge operation, there are 2 piles left, and we can't merge anymore. So the task is impossible.
Example 3:this
Input: stones = [3,5,1,2,6], K = 3 Output: 25 Explanation: We start with [3, 5, 1, 2, 6]. We merge [5, 1, 2] for a cost of 8, and we are left with [3, 8, 6]. We merge [3, 8, 6] for a cost of 17, and we are left with [17]. The total cost was 25, and this is the minimum possible.
Note:spa
1 <= stones.length <= 30
2 <= K <= 30
1 <= stones[i] <= 100
有 N
堆石頭排成一排,第 i
堆中有 stones[i]
塊石頭。code
每次移動(move)須要將連續的 K
堆石頭合併爲一堆,而這個移動的成本爲這 K
堆石頭的總數。htm
找出把全部石頭合併成一堆的最低成本。若是不可能,返回 -1
。
示例 1:
輸入:stones = [3,2,4,1], K = 2 輸出:20 解釋: 從 [3, 2, 4, 1] 開始。 合併 [3, 2],成本爲 5,剩下 [5, 4, 1]。 合併 [4, 1],成本爲 5,剩下 [5, 5]。 合併 [5, 5],成本爲 10,剩下 [10]。 總成本 20,這是可能的最小值。
示例 2:
輸入:stones = [3,2,4,1], K = 3 輸出:-1 解釋:任何合併操做後,都會剩下 2 堆,咱們沒法再進行合併。因此這項任務是不可能完成的。.
示例 3:
輸入:stones = [3,5,1,2,6], K = 3 輸出:25 解釋: 從 [3, 5, 1, 2, 6] 開始。 合併 [5, 1, 2],成本爲 8,剩下 [3, 8, 6]。 合併 [3, 8, 6],成本爲 17,剩下 [17]。 總成本 25,這是可能的最小值。
提示:
1 <= stones.length <= 30
2 <= K <= 30
1 <= stones[i] <= 100
1 class Solution { 2 struct State: Hashable { 3 var range: Range<Int>, pileCount: Int 4 } 5 6 func mergeStones(_ stones: [Int], _ K: Int) -> Int { 7 guard (stones.count - 1) % (K - 1) == 0 else { 8 return -1 9 } 10 11 let prefixSum: [Int] = stones.reduce(into: [0]) { $0.append($0.last! + $1) } 12 func sum(in range: Range<Int>) -> Int { 13 return prefixSum[range.upperBound] - prefixSum[range.lowerBound] 14 } 15 16 var states: [State: Int] = [:] 17 func minCost(in range: Range<Int>, pileCount: Int) -> Int { 18 if let result = states[State(range: range, pileCount: pileCount)] { 19 return result 20 } 21 guard range.count != pileCount else { 22 return 0 23 } 24 guard pileCount != 1 else { 25 return minCost(in: range, pileCount: K) + sum(in: range) 26 } 27 28 var result = Int.max 29 for split in stride(from: range.lowerBound + 1, to: range.upperBound, by: K - 1) { 30 let first = minCost(in: range.lowerBound..<split, pileCount: 1) 31 let second = minCost(in: split..<range.upperBound, pileCount: pileCount - 1) 32 33 result = min(result, first + second) 34 } 35 36 states[State(range: range, pileCount: pileCount)] = result 37 return result 38 } 39 40 return minCost(in: stones.indices, pileCount: 1) 41 } 42 }
44ms
1 class Solution { 2 private var cache = [[[Int?]]]() 3 private var prefixSum = [Int]() 4 private var K = 0 5 func mergeStones(_ stones: [Int], _ K: Int) -> Int { 6 guard stones.count != 1 else { return 0 } 7 guard (stones.count - 1) % (K - 1) == 0 else { return -1 } 8 guard stones.count >= K else { return -1 } 9 10 self.K = K 11 12 for i in 0..<stones.count { 13 var iArr = [[Int?]]() 14 for j in 0..<stones.count { 15 var jArr = [Int?]() 16 for k in 0...K { 17 if i == j || k == j - i + 1 { 18 jArr.append(0) 19 } else { 20 jArr.append(nil) 21 } 22 } 23 iArr.append(jArr) 24 } 25 cache.append(iArr) 26 } 27 28 prefixSum = [0] 29 30 for stone in stones { 31 prefixSum.append(prefixSum[prefixSum.count - 1] + stone) 32 } 33 34 return dp(0, stones.count - 1, 1) 35 } 36 37 private func dp(_ i: Int, _ j: Int, _ k: Int) -> Int { 38 if let val = cache[i][j][k] { 39 return val 40 } 41 42 let result: Int 43 44 if k == 1 { 45 result = dp(i, j, K) + prefixSum[j + 1] - prefixSum[i] 46 } else { 47 var minimum = 9999999999999 48 var t = i 49 while t < j { 50 minimum = min(minimum, dp(i, t, 1) + dp(t + 1, j, k - 1)) 51 t += (K - 1) 52 } 53 result = minimum 54 } 55 56 cache[i][j][k] = result 57 return result 58 } 59 }
Runtime: 380 ms
1 class Solution { 2 func mergeStones(_ stones: [Int], _ K: Int) -> Int { 3 var n:Int = stones.count 4 var pre:[Int] = [Int](repeating:0,count:n + 1) 5 for i in 1...n 6 { 7 pre[i] = pre[i - 1] + stones[i - 1] 8 } 9 var inf:Int = 1000000000 10 var dp:[[[Int]]] = [[[Int]]](repeating:[[Int]](repeating:[Int](repeating:inf,count:205),count:205),count:205) 11 for i in 1...n 12 { 13 dp[i][i][1] = 0 14 } 15 for len in 1...n 16 { 17 var i:Int = 1 18 while(i + len - 1 <= n) 19 { 20 var j:Int = i + len - 1 21 if len >= 2 22 { 23 for k in 2...len 24 { 25 var t:Int = i 26 while(t + 1 <= j) 27 { 28 dp[i][j][k] = min(dp[i][j][k], dp[i][t][k - 1] + dp[t + 1][j][1]) 29 t += 1 30 } 31 } 32 } 33 dp[i][j][1] = min(dp[i][j][1], dp[i][j][K] + pre[j] - pre[i - 1]) 34 i += 1 35 } 36 } 37 if dp[1][n][1] >= inf 38 { 39 return -1 40 } 41 return dp[1][n][1] 42 } 43 }