暴力递归到动态规划--纸牌博弈问题

  • 题目

数量为N的纸牌,排成一排,每次只能取最左或最右的纸牌。现有赌怪两个,一个先手拿一个后手拿,拿到牌累加后较大者获胜,问获胜者拿取的牌加起来有多大。
在这里插入图片描述

解法:
1)写出递归

当纸牌长度为N时,假设赌怪1是先手,那么赌怪2就是后手;但纸牌长度为N-1时,赌怪1就变成了后手,而赌怪2是先手。故需要两个函数来进行递归。

先手函数:当left==right,只剩一张牌了,那肯定是先手的拿这张牌,所以返回这张牌。若不止一张牌,那么先手就要在这两种情况中选取较大值:
拿掉左边的牌然后在剩下的纸牌中充当后手;
拿掉右边的牌然后在剩下的牌中充当后手。

后手函数:当left==right,只剩一张牌了,那么后手只能拿空气,所以返回零。若不止一张牌,那么后手要想怎么让对方下一次拿牌拿较小值。
拿掉左边的牌,在剩下的牌中充当先手;
拿掉右边的牌,在剩下的牌中充当先手。
在这里插入图片描述

2)由递归写出动态规划版本

在这里插入图片描述
·从递归函数看出,可变参为纸牌左右边界坐标left和right,他们的值是由总牌数决定的。也就是假设N张牌,left和right的范围均为0~N-1(先不考虑left实际上不会大于right)
那么我们可以确定表的大小,由于存在两个函数,所以需要两张表。
在这里插入图片描述
·我们再假设一组例子
int array[ ] = {3,5,7,4,3},考虑上述所说left和right的关系,表格中的下三角区域是不必考虑的。
在这里插入图片描述
·把目标格子和不依赖其他格子即可获得值的格子填上去,即只剩一张牌时(对角线),先手表中肯定是拿到牌的,而后手表拿空气,所以是零,如下图。
在这里插入图片描述
·然后我们再来看递归函数依赖情况,由此来确认表格元素的依赖关系。
在这里插入图片描述
在这里插入图片描述
先看先手,可看出是由后手表中坐标(left+1,right)的值加上array[left]的值和后手表中坐标(left,right-1)的值加上array[right]的值决定的,谁大,先手表中该位置就是该值。

同理可推出后手表,是由先手表中坐标(left+1,right)和(left,right-1)的值决定的。

找出依赖关系后尝试填一下表
例如点LR(0,1)= max(array[0]+后手表LR(1,1),array[1],后手表LR(0,0)) = 5
后手表中也同理,转移函数其实就是根据递归调用方式求出来的。
在这里插入图片描述
下面我们直接写出动态规划版本。
在这里插入图片描述

在这里插入图片描述

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值