Lintcode刷题-1861 · 老鼠跳跃-Go语言

Lintcode刷题-1861 · 老鼠跳跃-Go语言

1861 · 老鼠跳跃 困难

描述

有一个老鼠从高为n的楼梯顶部跳跃下来,这个老鼠在偶数次跳跃时可以跳1, 3或者4个台阶,奇数次可以跳跃1, 2或者4个台阶。但是楼梯中间会有一些台阶上有胶水,如果跳到那些台阶上,老鼠就会被直接粘住,无法继续跳跃。你需要求出从这个楼梯顶部开始,老鼠有多少种方法能够到达地面,即第0层。若超过地面,也算是可以到达。例如从1跳跃到-1,和从1跳跃到0的方案不同。楼梯有无胶水的状态是从高往低输入的,即arr[0]为楼梯的顶部。
其中,arr[i] == 0代表当前老鼠所在的位置无胶水,arr[i] == 1代表当前老鼠所在的位置有胶水。

2<=n<=50000
arr[i]=1代表台阶上有胶水,0代表没有
输入保证a[0] = a[n-1] = 0
答案需对1e9+7 取模

样例

样例1:

输入:
[0,0,0]
输出:
5
解释:
楼梯总共有3层。
第2层为起点,无胶水。
第1层,无胶水。
第0层,无胶水。
老鼠的跳法为:
2--odd(1)-->1--even(1)-->0
2--odd(1)-->1--even(3)-->-2
2--odd(1)-->1--even(4)-->-3
2--odd(2)-->0
2--odd(4)-->-2

样例2:

输入:
[0,0,1,0]
输出:
3
解释:
楼梯总共有4层。
第3层为起点,无胶水。
第2层,无胶水。
第1层,有胶水。
第0层,无胶水。

思路

算法 DP动态规划

DP方程

dp[i][0/1]表示奇数次/偶数次跳到i位置的方案数

0代表even偶数

1代表odd奇数

由于题目的arr是从高到低给出的,那么arr[0]就是我们的最高层

for i 0:n
这种枚举方式就是从高层到底层

DP边界条件

dp[0][0]=1

偶数次跳到了0位置,那么下次就是奇数次(也就是第一次)

DP转移

如果奇数次跳到了i,那么i再往下跳应该是偶数次

如果偶数次跳到了i,那么i再往下跳应该是奇数次

奇数次可以跳1,2,4 偶数次可以跳1,3,4

dp[i][0]去更新dp[i+odd][1]

dp[i][1]去更新dp[i+even][0]

伪代码中i只用枚举到n-2,不枚举到n-1的原因是 n-1已经是地面了 不能再往下跳

func ratJump(arr []int) int {
	const MOD = 1e9 + 7
	n := len(arr)
	dp := make([][]int64, n+4)
	for i := range dp {
		dp[i] = make([]int64, 2)
	}
	dp[0][0] = 1
	odd := []int{1, 2, 4}
	even := []int{1, 3, 4}
	for i := 0; i < n-1; i++ {
		for j := 0; j < 3; j++ {
			if i+odd[j] >= n || arr[i+odd[j]] == 0 {
				dp[i+odd[j]][1] += dp[i][0]
				dp[i+odd[j]][1] %= MOD
			}
			if i+even[j] >= n || arr[i+even[j]] == 0 {
				dp[i+even[j]][0] += dp[i][1]
				dp[i+even[j]][0] %= MOD
			}
		}
	}
	res := int64(0)
	for i := n - 1; i < n+4; i++ {
		res = (res + dp[i][0] + dp[i][1]) % MOD
	}
	return int(res)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值