请查看我遇到的这个问题:
“你和你八岁的侄子Elmo决定玩一个简单的纸牌游戏。一开始 在比赛中,牌面朝上排成一排。每张卡的价值都不同 分数。在发出所有牌之后,你和Elmo轮流移除最左边的牌或者 行中最右边的卡片,直到所有卡片都消失了。在每个回合,你可以决定哪一个 要拿两张牌。游戏的赢家是收集了最多积分的玩家 当比赛结束。 从来没有参加算法课程,Elmo遵循明显的贪婪策略?当它发生时 轮到他了,Elmo总是拿着价值更高的牌。你的任务是找到一个策略 只要有可能就会击败Elmo。 (对于像这样的小孩来说,这似乎是有意义的,但是 当成年人让他获胜时,Elmo绝对讨厌它。)
描述并分析一种算法,根据卡的初始序列确定 你可以收集与Elmo比赛的最大分数。“
我已经完成了这个问题的大部分理论工作。例如,我已经完成了DP所需的optimus子结构演示,并且我已经定义了Recursive低效表单,它解释了游戏是如何完成的。现在,下一步是设计一个自下而上的算法,可以有效地解决这个问题,或者,如果有帮助的话,可以自上而下地解决这个问题。我不能做任何一件事。你会如何解决这个问题?
答案 0 :(得分:0)
算法很简单,你可以用这种方式使用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
答案 1 :(得分:0)
这是一个允许您选择两个玩家策略的解决方案。您可以使用它来解决给定的问题,但您也可以将玩家的策略设置为“optimal_strategy”以找到minimax解决方案。
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)