动态规划-------一个简单爬梯子问题

来源:互联网 发布:查看淘宝店铺注册时间 编辑:程序博客网 时间:2024/06/09 19:42

问题描述

一个楼梯有20级,每次走1级或两级,请问从底走到顶一共有多少种走法?

 

分析:假设从底走到第n级的走法有f(n)种,走到第n级有两个方法,一个是从(n-1)级走一步,另一个是从第(n-2)级走两步,前者有f(n-1)种方法,后者有f(n-2)种方法,所以有f(n)=f(n-1)+f(n-2),还有f(0)=1,f(1)=1.递归编程实现程序1#include <stdio.h>int f(int n){    if(n==0 || n==1) return 1;   else return f(n-1)+f(n-2);}int main(){     printf("%d/n",f(20));    return 0;}现在来说说动态规划的基本思想动态规划的关键是发现子问题和怎么记录子问题,以上面的例子说明(1)对子问题可递归的求解,当n>1时,f(n)=f(n-1)+f(n-2);否则,f(1)=f(0)=1;(2)这些子问题是有重叠的,即求解某个问题时,某些子问题可能需要求解多次。例如求解f(5)时,f(2)就被求解了3次。在上面两个条件下,用动态规划的方式来求解会高效很多。就是把子问题记录下来,每个子问题只求解一次,从而提高了效率。程序2#include <stdio.h>
int result[100];
int f(int n)
{
  int res;
  if(result[n]>=0) return result[n];
  if(n==0 || n==1) res=1;
  else res=f(n-1)+f(n-2);
  result[n]=res;
  return res;
}
int main()
{
  int i;
  for(i=0;i<=20;i++)
    result[i]=-1;
  printf("%d/n",f(20));
  return 0;
}
程序3#include <stdio.h>
int f[100];
int main()
{
  int i;
  f[0]=1;
  f[1]=1;
  for(i=2;i<=20;i++)
    f[i]=f[i-1]+f[i-2];
  printf("%d",f[20]);
  return 0;
}
程序3是否让你想起了那个兔子繁殖的问题呢?

小结一下

动态规划,采用分治的策略,把求最优解问题分解为求若干子问题的最优解,记录子问题的解,化繁为简,很实用,也很高效。