Python练习(1):递归和动态规划的简单应用

首先考虑一个问题,假如我们在某个编译器上写出了这样的式子:(i++)(i++)(i++),假设i = 5,那么会有多少可能的结果?

显然,编译器对这种行为是未定义的,我们不知道i自增和乘法指令的执行顺序,可能的结果有5*5*5, 5*5*6, 5*5*7, 5*6*6, 5*6*7一共5种.那么问题来了,假如n个i++相乘,可能会有多少种情况???

对这个问题有多种解法,首先可以将其看作一个类似于排列组合的问题,假设乘法指令固定(n-1个),那么自增指令的可能位置右多少种?

注意到最后一个自增指令一定在最后一个乘法指令之后,实际上我们只需要考虑n-1个自增指令的位置,且注意到第i各乘法指令之前至多有i个自增指令,那么我们可以根据此写出递归方程,F[n][m] = F[n-1][m-1] + F[n-1][m],这实际上就是将问题分解成为两种简单一点的情况,当前要考虑的自增指令是否会在当前问题的第一个乘法指令前执行,如执行,则是F[n-1][m-1],否则 F[n-1][m];最后再考虑F[1][m],F[1][m] = 1+m,F[n][1] = n+1;从而可以写出递归的程序求解.

#recursion
def do_func(n,m):
    if(n == 1):
        return m+1
    elif (m==1):
        return n+1
    else:
        return do_func(n-1,m)+do_func(n-1,m-1)
def func(n):#this function is to make the user understand easier
    return do_func(n-1,n-1)

但是要注意到一点,直接使用递归会导致内存以及时间开销都很大,因为很多状态在前面某次递归中我们已经求出来了,所以我们把它转换为动态规划:

注意以下创建list的办法!!

#dynamic plan
def do_func2(n,m):
    F = [([0]*m) for i in range(n)]
    for k in range(1,n):
        F[1][k] = k+1
        F[k][1] = k+1
    for i in range(2,n):
        for j in range(2,m):
            F[i][j] = F[i-1][j]+ F[i-1][j-1]
    return F[n-1][m-1]
def func2(n):
    return do_func2(n,n)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值