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

问题描述

一个楼梯有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
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
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
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是否让你想起了那个兔子繁殖的问题呢?

小结一下

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


你可能感兴趣的:(嵌入式技术C语言篇)