【问题标题】:Dynamic Programming Card Game动态规划卡牌游戏
【发布时间】:2013-05-12 02:56:36
【问题描述】:

请检查我遇到的这个问题:

“你和你八岁的侄子 Elmo 决定玩一个简单的纸牌游戏。一开始 游戏中,牌面朝上一排。每张卡价值不同的数字 的点。发完所有牌后,您和 Elmo 轮流移除最左边的或 从行中最右边的卡,直到所有的卡都消失了。在每一轮,你可以决定哪一个 两张牌拿。游戏的获胜者是获得最多积分的玩家 当游戏结束时。 从来没有上过算法课,Elmo 遵循明显的贪婪策略?什么时候? 轮到他时,Elmo 总是拿点值较高的牌。你的任务是找到策略 只要有可能,它就会击败 Elmo。 (像这样殴打一个小孩似乎很卑鄙,但是 当大人让他赢时,Elmo 绝对讨厌它。)

描述和分析一个算法,以确定给定初始卡片序列, 与 Elmo 对抗时,您可以获得的最大积分。”

我已经完成了这个问题的大部分理论工作。例如,我已经完成了 DP 所需的 optimus 子结构演示,并且我定义了递归低效形式,它解释了游戏是如何完成的。现在下一步是设计一个自下而上的算法来有效地解决这个问题,或者,如果它可能有帮助的话,一个自上而下的记忆解决方案。我只是不能做任何一个。你会如何解决这个问题?

【问题讨论】:

标签: algorithm recursion dynamic-programming memoization bottom-up


【解决方案1】:

算法简单,可以这样使用memoization和动态规划:

def findMax(mem, cards, myTurn):
    maxValue = 0
    if(not cards):
        return 0
    if str(cards) in mem: #If we have already compute this state
        return mem[str(cards)]
    elif not myTurn: #turn of Elmo
        if cards[0] > cards[len(cards) - 1]:
            maxValue = findMax(mem, cards[1:], True)
        else:
            maxValue = findMax(mem, cards[:-1], True)
    else: #your turn
        maxValue = max(cards[0] + findMax(mem, cards[1:], False), cards[len(cards) - 1] + findMax(mem, cards[:-1], False))
    mem[str(cards)] = maxValue  #Store the max value for this state
    return maxValue

import random
size = int(10 + random.randint(0,1))
cards = [random.randint(0,50) for x in range(size)]
print "Cards" + str(cards)
print findMax({}, cards, True)

输出:

Cards: [28, 33, 48, 0, 26, 1, 3, 11, 22, 32, 12]
Max value: 120

【讨论】:

    【解决方案2】:

    这是一个允许您选择两个玩家的策略的解决方案。您可以使用它来解决给定的问题,但您也可以将两个玩家的策略设置为“optimal_strategy”以找到极小极大解决方案。

    import random
    
    def greedy_strategy(s0, s1, cards, i, j, cache):
        if i == j: return 0
        if cards[i] >= cards[j - 1]:
            return cards[i] - s1(s1, s0, cards, i + 1, j, cache)
        else:
            return cards[j - 1] - s1(s1, s0, cards, i, j - 1, cache)
    
    def optimal_strategy(s0, s1, cards, i, j, cache):
        if i == j: return 0
        key = (i, j)
        if key not in cache:
            left = cards[i] - s1(s1, s0, cards, i + 1, j, cache)
            right = cards[j - 1] - s1(s1, s0, cards, i, j - 1, cache)
            cache[key] = max(left, right)
        return cache[key]
    
    def score_play(cards, s0, s1):
        # How many points you'll win by
        adv = s0(s0, s1, cards, 0, len(cards), {})
        # my_score + opp_score = sum(cards)
        # my_score - opp_score = adv
        # adding: 2 * my_score = sum(cards) + adv
        # Therefore my_score is this...
        return (sum(cards) + adv) // 2
    
    for _ in xrange(10):
        cards = range(20)
        random.shuffle(cards)
        print cards, score_play(cards, optimal_strategy, greedy_strategy)
    

    【讨论】:

      猜你喜欢
      • 2017-08-02
      • 1970-01-01
      • 1970-01-01
      • 2020-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-08
      • 1970-01-01
      相关资源
      最近更新 更多