• [Swift]LeetCode1140. 石子游戏 II | Stone Game II


    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(shanqingyongzhi)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址:https://www.cnblogs.com/strengthen/p/11258434.html 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    Alex and Lee continue their games with piles of stones.  There are a number of piles arranged in a row, and each pile has a positive integer number of stones piles[i].  The objective of the game is to end with the most stones. 

    Alex and Lee take turns, with Alex starting first.  Initially, M = 1.

    On each player's turn, that player can take all the stones in the first X remaining piles, where 1 <= X <= 2M.  Then, we set M = max(M, X).

    The game continues until all the stones have been taken.

    Assuming Alex and Lee play optimally, return the maximum number of stones Alex can get.

    Example 1:

    Input: piles = [2,7,9,4,4]
    Output: 10
    Explanation:  If Alex takes one pile at the beginning, Lee takes two piles, then Alex takes 2 piles again. Alex can get 2 + 4 + 4 = 10 piles in total. If Alex takes two piles at the beginning, then Lee can take all three piles left. In this case, Alex get 2 + 7 = 9 piles in total. So we return 10 since it's larger. 

    Constraints:

    • 1 <= piles.length <= 100
    • 1 <= piles[i] <= 10 ^ 4

    亚历克斯和李继续他们的石子游戏。许多堆石子 排成一行,每堆都有正整数颗石子 piles[i]。游戏以谁手中的石子最多来决出胜负。

    亚历克斯和李轮流进行,亚历克斯先开始。最初,M = 1

    在每个玩家的回合中,该玩家可以拿走剩下的 前 X 堆的所有石子,其中 1 <= X <= 2M。然后,令 M = max(M, X)

    游戏一直持续到所有石子都被拿走。

    假设亚历克斯和李都发挥出最佳水平,返回亚历克斯可以得到的最大数量的石头。

    示例:

    输入:piles = [2,7,9,4,4]
    输出:10
    解释:
    如果亚历克斯在开始时拿走一堆石子,李拿走两堆,接着亚历克斯也拿走两堆。在这种情况下,亚历克斯可以拿到 2 + 4 + 4 = 10 颗石子。 
    如果亚历克斯在开始时拿走两堆石子,那么李就可以拿走剩下全部三堆石子。在这种情况下,亚历克斯可以拿到 2 + 7 = 9 颗石子。
    所以我们返回更大的 10。 

    提示:

    • 1 <= piles.length <= 100
    • 1 <= piles[i] <= 10 ^ 4

    8ms
     1 class Solution {
     2     private var sums = [Int](repeating: 0, count: 101)
     3     private var hash = [[Int]](repeating: [Int](repeating: 0, count: 101), count: 101)
     4     func stoneGameII(_ piles: [Int]) -> Int {
     5         let N = piles.count
     6         if N == 0 { return 0 }
     7         sums[N-1] = piles[N-1]
     8         for i in stride(from: N-2, to: -1, by: -1) {
     9             sums[i] = sums[i+1] + piles[i]
    10         }
    11        
    12         return helper(piles, 0, 1)
    13     }
    14 
    15 
    16     private func helper(_ a: [Int], _ i: Int, _ M: Int) -> Int {
    17         if i == a.count { return 0 }
    18         if 2*M >= a.count - i { return sums[i] }
    19         if hash[i][M] != 0 { return hash[i][M] }
    20 
    21         var minv = Int.max //the min value the next player can get
    22         for x in 1..<2*M+1 {
    23             minv = min(minv, helper(a, i+x, max(M,x)))
    24         }
    25         hash[i][M] = sums[i] - minv  //max stones = all the left stones - the min stones next player can get
    26         return hash[i][M]
    27     }
    28 }

    Runtime: 16 ms

    Memory Usage: 21 MB
     1 class Solution {
     2     func stoneGameII(_ piles: [Int]) -> Int {
     3         var n:Int = piles.count
     4         var sums:[Int] = [Int](repeating:0,count:n + 1)
     5         for i in stride(from:n - 1,through:0,by:-1)
     6         {
     7             sums[i] = piles[i] + sums[i+1]
     8         }
     9         var dp:[[Int]] = [[Int]](repeating:[Int](repeating:0,count:n + 1),count:n)
    10         for i in stride(from:n - 1,through:0,by:-1)
    11         {
    12             for j in 1...n
    13             {
    14                 if 2 * j >= n - i
    15                 {
    16                     dp[i][j]=sums[i]
    17                 }
    18                 else
    19                 {
    20                     for k in 1...(2*j)
    21                     {
    22                         let nextM:Int = max(k,j)
    23                         dp[i][j] = max(dp[i][j],sums[i] - dp[i+k][nextM])
    24                     }
    25                 }
    26             }
    27         }
    28         return dp[0][1]
    29     }
    30 }

    20ms 
     1 class Solution {
     2     func stoneGameII(_ piles: [Int]) -> Int {
     3         guard !piles.isEmpty else { return 0 }
     4         
     5         var hash = [Key:Int]()
     6         var sums = Array(repeating: 0, count: piles.count)
     7         sums[0] = piles[0]
     8         for i in 1..<piles.count {
     9             sums[i] = sums[i-1] + piles[i]
    10         }
    11         return _stoneGameII(sums, 0, 1, &hash)
    12     }
    13     
    14     func _stoneGameII(_ sums: [Int], _ i: Int, _ m: Int, _ hash: inout [Key:Int]) -> Int {
    15         if i >= sums.count { return 0 }
    16         
    17         let key = Key(i,m)
    18         if let result = hash[key] { return result }
    19         
    20         var result = Int.max
    21         for x in (i..<min(sums.count, (i + m * 2))) {
    22             result = min(result, _stoneGameII(sums, x+1, max(m, x - i + 1), &hash))
    23         }
    24         
    25         result = sums[sums.count - 1] - (i == 0 ? 0 : sums[i - 1]) - result
    26         
    27         hash[key] = result
    28         return result
    29     }
    30 }
    31 
    32 struct Key: Hashable {
    33     let i: Int
    34     let m: Int
    35     
    36     init(_ i: Int, _ m: Int) {
    37         self.i = i
    38         self.m = m
    39     }
    40 }

    40ms

     1 class Solution {
     2     var m = [[Int]]()
     3     func stoneGameII(_ piles: [Int]) -> Int {
     4         var sum = piles.reduce(0){$0 + $1}
     5         m = [[Int]](repeating:[Int](repeating: Int.min, count: 2 * piles.count), count: piles.count)
     6         let diff = dfsHelper(piles, 0, 1)
     7         return (sum - diff) / 2 + diff
     8     }
     9     
    10     fileprivate func dfsHelper(_ piles:[Int], _ idx:Int, _ M:Int) -> Int {
    11         
    12         
    13         if idx >= piles.count {
    14             return 0
    15         }
    16         if m[idx][M] > 0 { return m[idx][M] } 
    17     
    18         var sum = 0
    19         for i in idx...min(idx + 2 * M - 1, piles.count - 1) {
    20             sum += piles[i]
    21             m[idx][M] = max(m[idx][M], sum - dfsHelper(piles, i+1, max(M, (i - idx)+1)))
    22         }
    23         return m[idx][M]
    24     }
    25 }

    192ms

     1 class Solution {
     2     func stoneGameII(_ piles: [Int]) -> Int {
     3         guard !piles.isEmpty else { return 0 }
     4         
     5         var hash = [Key:Int]()
     6         return _stoneGameII(piles, 0, 1, true, &hash)
     7     }
     8     
     9     func _stoneGameII(_ piles: [Int], _ i: Int, _ m: Int, _ player: Bool, _ hash: inout [Key:Int]) -> Int {
    10         if i >= piles.count { return 0 }
    11         
    12         let key = Key(i,m,player)
    13         if let result = hash[key] { return result }
    14         
    15         var result = player ? Int.min : Int.max
    16         for x in (i..<min(piles.count, (i + m * 2))) {
    17             
    18             if player { // I am the player, maximize the results
    19                 let sum = piles[i...x].reduce(0,+)
    20                 result = max(result, sum + _stoneGameII(piles, x+1, max(m, x - i + 1), !player, &hash))    
    21             } 
    22             else { // I am the opponent, minimize the results
    23                 // Note we don't do "sum + _stoneGame" because we are 
    24                 // only interested in player's result (number of stones)
    25                 result = min(result, _stoneGameII(piles, x+1, max(m, x - i + 1), !player, &hash))    
    26             }
    27             
    28         }
    29         
    30         hash[key] = result
    31         return result
    32     }
    33 }
    34 
    35 struct Key: Hashable {
    36     let i: Int
    37     let m: Int
    38     let player: Bool
    39     
    40     init(_ i: Int, _ m: Int, _ player: Bool) {
    41         self.i = i
    42         self.m = m
    43         self.player = player
    44     }
    45 }
  • 相关阅读:
    Java CodeForces 1230A
    基于Lucene的全文检索实践
    错误解决:ElasticSearch SearchResponse的Hits[]总是比totalHits少一条记录
    Java CodeForces 266A
    jQuery 幻灯片插件 OwlCarousel22.3.4 使用
    由于找不到 MSVCP100.dll,无法继续执行代码。重新安装程序可能会解决此问题。
    idea 单行注释,紧跟代码第一列
    TrayPwrD3 电脑一直处于使用独显的状态
    ubuntu20.04 域名解析暂时失败
    jQuery 幻灯片插件 owl_carousev1.31 使用
  • 原文地址:https://www.cnblogs.com/strengthen/p/11258434.html
Copyright © 2020-2023  润新知