395.硬币排成线2

题目描述:

有 n 个不同价值的硬币排成一条线。两个参赛者轮流从左边依次拿走 1 或 2 个硬币,直到没有硬币为止。计算两个人分别拿到的硬币总价值,价值高的人获胜。

请判定第一个玩家是输还是赢?

样例:

给定数组 A = [1,2,2], 返回 true.

给定数组 A = [1,2,4], 返回 false.

动态规划的解法:
①建立数组DP[i]表示拿第i个硬币到第n个硬币所能获得的最大利润
②对于玩家拿到第i个硬币时,玩家拿硬币仍是从左往右拿。因此他有两种选择,仅拿第i个硬币或者拿第i和i+1个硬币,这两种算法均会产生一个价值作为DP[i]的值;因为我们是从后往前进行动态规划
③第二个玩家在我们做出选择后也会对第一个玩家的利益进行限制,例如当第一个玩家拿第i个硬币时,他可以拿第i+1或第i+1、i+2个硬币,但是他会对结果进行判断,保证第一个玩家的获利达到最小,即选择DP[i + 2]和DP[i + 3]中的最小值来决定自己是拿一个还是拿两个
综上,动态规划表达式为DP[i] = max{nums[i] + min{DP[i + 2], DP[i + 3]}, num[i] + num[i + 1] + min{DP[i + 3], DP[i + 4]}};

n = len(values)
if n == 0:
	return False
if n < 3:
	return True
DP = [0] * (1 + n)
DP[n] = 0
DP[n - 1] = values[n - 1]
DP[n - 2] = values[n - 1] + values[n - 2]
DP[n - 3] = values[n - 2] + values[n - 3]
for i in range(n - 4, -1, -1):
	DP[i] = values[i] + min(DP[i + 2], DP[i + 3])
	DP[i] = max(DP[i], values[i] + values[i + 1] + min(DP[i + 3], DP[i + 4]))
summ = sum(values)
return DP[0] * 2 > summ

速度还行
上面算法时间复杂度O(n),空间复杂度O(n)

利用滚动数组,可以使空间复杂度降到O(1)

if not values:
            return False
            
        if len(values) <= 2:
            return True
            
        n = len(values)
        
        # dynamic programming
        f = [0] * 3
        prefix_sum = [0] * 3
        f[(n - 1) % 3] = prefix_sum[(n - 1) % 3] = values[n - 1]

        # traverse values in reverse order from n-1 to 0
        for i in range(n - 2, -1, -1):
            prefix_sum[i % 3] = prefix_sum[(i + 1) % 3] + values[i]
            f[i % 3] = max(
                values[i] + prefix_sum[(i + 1) % 3] - f[(i + 1) % 3],
                values[i] + values[i + 1] + prefix_sum[(i + 2) % 3] - f[(i + 2) % 3],
            )
        return f[0] > prefix_sum[0] - f[0]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值