算法题 - 卡牌游戏问题 - Python

问题描述:

卡牌游戏问题

  小a和小b玩一个游戏,有 n张卡牌,每张上面有两个正整数 xy。取一张牌时,个人积分增加 x,团队积分增加 y。求小a,小b各取若干张牌,使得他们的 个人积分相等,且 团队积分最大

用例描述:

输入:
4  # n=4 组数据
3 1  # x, y
2 2
1 4
1 4
输出:10  # 团队积分最大为10

问题分析:

这个题目类似01背包问题,我们可以这样理解,小a的得分 - 小b的得分 = 0,所以每组数据可以设置三种状态k = (-1, 0, 1)-1表示这张卡牌小a要,0表示这个卡牌谁也不要,1表示这张卡牌小b要。

(1)方法1:现在可以使用穷举法,找到所有组合,然后获取团体得分的最大值,这个还可以使用三进制数,例如0、1、2,每一个组合一定会得出一个三进制数,然后遍历每一位,0不要,1给小a,2给小b,总之够麻烦。

(2)方法2,dp方法:从网上查考了很多方法,最终感觉还是这个方法比较简单易懂点。参考链接为:https://www.jianshu.com/p/83204e62ac94

# dp状态转换方程如下:

dp[i][j]=max(d[i-1][j], d[i-1][j-x[i-1]) + y[i-1], d[i-1][j+x[i-1]] + y[i-1])

# dp[i][j]表示前 i 张卡牌中,且两人得分的差为 j 时团队得分的最大值

Python3实现:

def getMaxGain(n, x, y):

    mx = max(x)  # 获取最大值,作为差的边界

    dp = [[0] * (mx+1) for _ in range(n+1)]  # 初始化dp

    for i in range(1, n+1):
        for j in range(mx+1):
            tmp1, tmp2 = 0, 0
            if j - x[i-1] >= 0:  # 这张卡牌给小a
                tmp1 = dp[i-1][j-x[i-1]] + y[i-1]

            if j + x[i - 1] <= mx:  # 这张卡牌给小b
                tmp2 = dp[i-1][j+x[i-1]] + y[i-1]

            dp[i][j] = max(dp[i - 1][j], tmp1, tmp2)  # 三种状态的最高得分

            if i == 1 and j == 0:  # 只有一张卡牌时
                dp[i][j] = 0
    return dp[n][0]


if __name__ == '__main__':
    n = 4
    x = [3, 2, 1, 1]
    y = [1, 2, 4, 4]
    print(getMaxGain(n, x, y))

声明:如有不妥或问题还请您,批评指正,自己只是学习总结,不涉及其他,大神略过哦。参考大神的部分已经给出链接,可以去学习他人的思路。

猜你喜欢

转载自blog.csdn.net/XX_123_1_RJ/article/details/81808305