首页 > 试题广场 >

纸牌博弈

[编程题]纸牌博弈
  • 热度指数:4957 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

有一个整型数组A,代表数值不同的纸牌排成一条线。玩家a和玩家b依次拿走每张纸牌,规定玩家a先拿,玩家B后拿,但是每个玩家每次只能拿走最左或最右的纸牌,玩家a和玩家b都绝顶聪明,他们总会采用最优策略。请返回最后获胜者的分数。

给定纸牌序列A及序列的大小n,请返回最后分数较高者得分数(相同则返回任意一个分数)。保证A中的元素均小于等于1000。且A的大小小于等于300。

测试样例:
[1,2,100,4],4
返回:101
# -*- coding:utf-8 -*-
#用first[j][i]表示先选的人能拿到的最高分,second[j][i]来表示后选的人能拿到的最高分
#对于先选者,他有两种选法
#1.若先选者选A[0],则对于后面的1,...,n-1数组,他就变成了后选者,此时能拿到的分为A[0]+S[1][n-1]
#2.若先选者选A[n-1],则对于前面的数组0,...,n-2,同样变为后选者,此时能拿到得分为A[n-1]+S[0][n-2];
#所以 F[0][n-1]=max(A[0]+S[1][n-1],A[n-1]+S[0][n-2])
#对于后选者,他能能到的最高分是受先选者控制的,即他只能选到先选者留给他的最小值,将其转化为数学形式就是
#S[l][r]=min(F[l+1][r],F[l][r-1])
#这里的最小值是先选者留给他的,他只能拿到最小值
class Cards:
    def cardGame(self, A, n):
        first=[[0 for i in range(n)] for i in range(n)]
        second=[[0 for i in range(n)] for i in range(n)]
        for i in range(n):
            first[i][i]=A[i]
            second[i][i]=0
            j=i-1
            while j>=0:
                first[j][i]=max(second[j+1][i]+A[j],second[j][i-1]+A[i])
                second[j][i]=min(first[j+1][i],first[j][i-1])
                j-=1
        return max(first[0][n-1],second[0][n-1])

发表于 2018-10-04 19:48:24 回复(0)
分享一个python代码
 # -*- coding:utf-8 -*-
class Cards:
    def cardGame(self, A, n):
        first = []
        second = []
        for i in range(n):
            first.append([0 for i in range(n)])
            second.append([0 for i in range(n)]) 
        first[0][0] = A[0]
        first[n-1][n-1]=A[n-1]
        for j in range(1,n):
            for i in range(n-2,-1,-1):
                if i<=j:
                    first[i][j] = max(second[i+1][j]+A[i],second[i][j-1]+A[j])
                    second[i][j] = min(first[i+1][j],first[i][j-1])
        return int(max(first[0][n-1],second[0][n-1]))

发表于 2017-07-10 22:59:20 回复(0)

问题信息

难度:
4条回答 15224浏览

热门推荐

通过挑战的用户

查看代码
纸牌博弈