动态规划

来源:互联网 发布:中超数据直播系统 编辑:程序博客网 时间:2024/06/05 04:12

动态规划

  • 动态规划
    • 爬楼梯
    • 抢劫房子


爬楼梯

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)=1
f(2)=2
当有n级台阶时,若我们第一步 走1级,还剩n-1级台阶要走,这n-1级台阶有f(n-1)种走法;若第一步走2级,还剩n-2级台阶要走,这n-1级台阶有f(n-2)种走法;因此
f(n)=f(n1)+f(n2)
这不就是斐波那契数列吗?
递归代码

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    n2end

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

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

Climbing Stairs


抢劫房子

题目:某天夜里,劫匪将在这条街抢劫,这条街上的每间房子都有不少钱,但是一旦抢了相邻的房子,就会自动触发警局里的警报。在不让警报响起的情况下最多能抢到多少钱。
其实就是给你一个序列,在这个序列中找出一个不相邻的子序列并使之和最大,求出这个和。

思路:一道典型的通过递推求解的动态规划问题,关键在于找出递推关系式。设f(n)是长度为n的数列 {an} 的不连续子序列的和最大值, 如果没有不允许相邻这个限制,显然有
f(n)=f(n1)+an
加上不允许相邻这个条件后,子序列取an便不能取an1, 那么取an时只能有
f(n)=f(n2)+an
子序列不取an时自然有
f(n)=f(n1)
为了使f(n)最大,取两者之大者即可。则有

f(1)=a1
f(2)=max(a1,a2)
f(n)=max(f(n1),f(n2)+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]    endend

House Robber


0 0
原创粉丝点击