笔试刷题 | 动态规划-博弈问题

#! /usr/bin/env python
# -*-coding:utf-8-*-
"""
Author: ChileWang
Created at 2020/03/20 15:59


Question:
问题:
有一排正数,代表数值不同的纸牌排成一条线,玩家A和玩家B都可以看到。


每位玩家在拿走数字的时候,都只能从最左和最右的数中选择一个。


玩家A先拿,玩家B再拿,两人交替拿走所有的数字,


两人都力争自己拿到的数的总和比对方多。请返回最后获胜者的分数。


 


例如:


5,2,3,4


玩家A先拿,当前他只能拿走5或者4。


如果玩家A拿走5,那么剩下2,3,4。轮到玩家B,此时玩家B可以选择2或4中的一个,…


如果玩家A拿走4,那么剩下5,2,3。轮到玩家B,此时玩家B可以选择5或3中的一个,…


Solution:
动态规划


"""




def card():
    """
    动态规划之博弈问题
    核心:斜着计算二维数组
    详细解析:https://zhuanlan.zhihu.com/p/107741899
    :return:
    """
    arr = [1, 2, 100, 4]
    arr = [3, 9, 1, 2]
    first = [[0] * len(arr) for _ in range(len(arr))]
    end = [[0] * len(arr) for _ in range(len(arr))]


    for i in range(len(arr)):
        first[i][i] = arr[i]


    for i in range(1, len(arr)):
        for j in range(len(arr)):
            if i + j < len(arr):
                first[j][j + i] = max(arr[j] + end[j+1][j + i], arr[j + i] + end[j][j + i - 1])
                end[j][j + i] = min(first[j + 1][j + i], first[j][j + i - 1])


    print(max(first[0][len(arr) - 1], end[0][len(arr)-1]))
    for s in first:
        print(s)
    print('-------')
    for s in end:
        print(s)
    return max(first[0][len(arr) - 1], end[0][len(arr)-1])




if __name__ == '__main__':
    card()

你可能感兴趣的:(笔试刷题 | 动态规划-博弈问题)