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

189 篇文章 3 订阅

问题描述:

卡牌游戏问题

  小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))

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值