算法题 – 卡牌游戏问题 – Python
问题描述:
卡牌游戏问题
小a和小b玩一个游戏,有
n
张卡牌,每张上面有两个正整数x
,y
。取一张牌时,个人积分增加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))
声明:如有不妥或问题还请您,批评指正,自己只是学习总结,不涉及其他,大神略过哦。参考大神的部分已经给出链接,可以去学习他人的思路。
版权声明:本文为XX_123_1_RJ原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。