小白兔拔萝卜问题的递归求解

0

进入

3

2

1

3

4

5

4

3

2

3

4

2

0

4

5

3

2

4

5

3

2

1

2

4

2

3

4

5

3

2

2

2

3

4

0

离开

小白兔从一片田地的左上角进入,右下角离开,田地中每个方格里有数量不等的萝卜供小白兔拿取,小白兔必须尽快离开田地以降低被猎人发现的概率(即小白兔每次必须选择向下或者向右走一格,并拿走格子里的萝卜),在保证尽可能安全的前提下,请为小白兔规划一条最佳的拿萝卜路径。

任务1-1:打开任务1.cpp,在函数diguiluobo中依照动态规划方程使用递归实现小白兔拔萝卜问题的动态规划求解。

任务1-2:比较小白兔拔萝卜问题的递归和递推求解执行时间,思考解决方法。

任务1-3:在函数jizhuluobo中利用备忘录方法在递归过程中记录并检查各个子问题的解,使递归方法达到和递推方法类似的求解效率。

(2)爬楼梯问题的备忘录求解

任务2:爬楼梯问题和斐波那契数列的计算极其相似,请在任务2.cpp中编写程序,利用备忘录的方法使递归程序达到和递推程序类似的求解效率。

任务3:如果爬楼梯问题允许一次最多上3个台阶,应该如何编写程序求解?

#include
#include
#include
const int M=15;//萝卜地行数
const int N=15;//萝卜地列数
int v[M][N],c[M][N];//萝卜数,最优萝卜数
int dituiluobo(int m,int n)
{
    //递推求解拔萝卜问题
      for(int i=0;i<=m;i++)
    for(int j=0;j<=n;j++)
    {
      if(i==0&&j==0) c[i][j]=v[i][j];
      if(i==0&&j!=0) c[i][j]=c[i][j-1]+v[i][j];
      if(i!=0&&j==0) c[i][j]=c[i-1][j]+v[i][j];
      if(i!=0&&j!=0)
        if(c[i][j-1]>c[i-1][j]) c[i][j]=c[i][j-1]+v[i][j];
        else c[i][j]=c[i-1][j]+v[i][j];
    }
  return c[m][n];
}
int diguiluobo(int m,int n)
{
    //递归求解拔萝卜问题
    if(m==0&&n==0) return v[m][n];
    if(m==0&&n!=0) return diguiluobo(m,n-1)+v[m][n];
    if(m!=0&&n==0) return diguiluobo(m-1,n)+v[m][n];
    if(m!=0&&n!=0) {
        int a=diguiluobo(m,n-1);
        int b=diguiluobo(m-1,n);
        if(a>b)        
            return a+v[m][n];
        else
            return b+v[m][n];
    }
}
int jizhuluobo(int m,int n)
{
    //备忘录优化递归求解
    return 0;
}
void xunlu(int m,int n)
{    
    printf("%d,%d\n",m,n);
    while(m!=0||n!=0)
        if(m==0){
            n--;
            printf("%d,%d\n",m,n);}
        else if(n==0){
            m--;
            printf("%d,%d\n",m,n);}
        else if(c[m-1][n]>c[m][n-1]){
            m--;
            printf("%d,%d\n",m,n);}
        else{
            n--;
            printf("%d,%d\n",m,n);}
}
int main()
{
    int i,j,start,end,t,count;
    printf("一片萝卜地如下:\n");
    for(i=0;i     {
        for(j=0;j         {
            v[i][j]=rand()%10;
            c[i][j]=0;
            printf("%d  ",v[i][j]);
        }
        printf("\n");
    }
    start=clock();
    count=diguiluobo(M-1,N-1);
    end=clock();
    t=end-start;
    printf("递归小萝卜结果为%d,耗费时间:%dms\n",count,t);
    start=clock();
    count=jizhuluobo(M-1,N-1);
    end=clock();
    t=end-start;
    printf("记住小萝卜结果为%d,耗费时间:%dms\n",count,t);
    start=clock();
    count=dituiluobo(M-1,N-1);
    end=clock();
    t=end-start;
    printf("递推小萝卜结果为%d,耗费时间:%dms\n",count,t);
    printf("萝卜矩阵如下:\n");
    for(i=0;i     {
        for(j=0;j         {
            printf("%d  ",c[i][j]);
        }
        printf("\n");
    }
    xunlu(M-1,N-1);
    return 0;
}
 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值