您的位置:首页 > 其它

动态规划

2015-07-01 16:01 148 查看

动态规划

动态规划
爬楼梯

抢劫房子

爬楼梯

You are climbing a stair case. It takes n steps to reach to the top.

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

为了熟悉动态规划的思维过程,我们先假装不知道这是斐波那契数列。设楼梯有n阶,则有f(n)种走法,显然有

f(1)=1f(1) = 1

f(2)=2f(2) = 2

当有n级台阶时,若我们第一步 走1级,还剩n-1级台阶要走,这n-1级台阶有f(n-1)种走法;若第一步走2级,还剩n-2级台阶要走,这n-1级台阶有f(n-2)种走法;因此

f(n)=f(n−1)+f(n−2)f(n) = f(n-1) + f(n-2)

这不就是斐波那契数列吗?

递归代码

def climb_stairs(n)
return 1 if n == 1
return 2 if n == 2
climb_stairs(n-1) + climb_stairs(n-2)
end


算法是没错的,只是结果超时,好多计算都重复了,写成累加的就AC了

def climb_stairs(n)
return 1 if n == 1
return 2 if n == 2
n1, n2, i= 1, 2, 2
(n - 2).times do n1, n2 = n2, n1 + n2 end
n2
end


还可以这么写,能短2行,意思其实是一样的。

def climb_stairs(n)
a = b = 1
n.times do a, b = b, a+b end
a
end


Climbing Stairs

抢劫房子

题目:某天夜里,劫匪将在这条街抢劫,这条街上的每间房子都有不少钱,但是一旦抢了相邻的房子,就会自动触发警局里的警报。在不让警报响起的情况下最多能抢到多少钱。

其实就是给你一个序列,在这个序列中找出一个不相邻的子序列并使之和最大,求出这个和。

思路:一道典型的通过递推求解的动态规划问题,关键在于找出递推关系式。设f(n)是长度为n的数列 {ana_n} 的不连续子序列的和最大值, 如果没有不允许相邻这个限制,显然有

f(n)=f(n−1)+anf(n) = f(n-1)+a_n

加上不允许相邻这个条件后,子序列取ana_n便不能取an−1a_{n-1}, 那么取ana_n时只能有

f(n)=f(n−2)+anf(n) = f(n-2)+a_n

子序列不取ana_n时自然有

f(n)=f(n−1)f(n) = f(n-1)

为了使f(n)f(n)最大,取两者之大者即可。则有

f(1)=a1f(1) = a_1

f(2)=max(a1,a2)f(2) = max(a_1, a_2)

f(n)=max(f(n−1),f(n−2)+n),n>2f(n) = max(f(n-1), f(n-2)+n), n>2

# Ruby
# @param {Integer[]} nums
# @return {Integer}
def rob(nums)
size = nums.size
case size
when 0
return 0
when 1
return nums[0]
when 2
return nums.max
else
res = [nums[0], [nums[0], nums[1]].max]
(2...size).each do |i| res << [res[i-1], res[i-2] + nums[i]].max end
return res[size - 1]
end
end


House Robber
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: