动态规划 小朋友过桥问题 C++版本 3中动态规划

//https://blog.csdn.net/u013309870/article/details/75193592 例1

【例题1】在一个夜黑风高的晚上,有n(n <= 50)个小朋友在桥的这边,现在他们需要过桥,但是由于桥很窄,每次只允许不大于两人通过,他们只有一个手电筒,所以每次过桥的两个人需要把手电筒带回来,i号小朋友过桥的时间为T[i],两个人过桥的总时间为二者中时间长者。问所有小朋友过桥的总时间最短是多少。

 

下面是源码,无解析!

提示几点:对于递归这种,大家脑海中想象成一个完全二叉树就好,递归就是把所有的结果和方案都过一遍

备忘录(常用于自顶向下把)就是,

记录最底层的已经解析的结果,然后使 函数回溯时能够提前结束递归。

 

#include <algorithm>

//过桥所需的时间How long time spend crossing the bridge
const int Times[]={1,2,5,10,7,9}; 


//自底向上的方法
int crossBridgeDownToUp(const int *Times, int n)
{
    //排序Times,此处省略
    int * costTime = new int[n];
    costTime[0] = Times[0];
    costTime[1] = Times[1];
    if (n <= 2)
    {
        return Times[n-1];
    }
    else{
         for (int i = 2; i<n; ++i)
         {
             costTime[i]=min(costTime[i-1] + Times[0] + Times[i],
                             Times[0] + 2 * Times[1] + Times[i] + costTime[i-2]);
          }  
        return costTime[n-1];  
     }
}

//自顶向下的方法
int crossBridgeUpToDown(int n)
{
    //排序Times,此处省略
    
    //记录结果
    if (n <= 2)
    {
        return Times[n-1];
    }
    
    return min(crossBridgeUpToDown(n-1) + Times[0] + Times[n-1],
                Times[0] + 2 * Times[1] + Times[n-1] + crossBridgeUpToDown(n-2)); 
}

//带备忘录式的自顶向下方法
int memoCrossBridge(int n, int *memoCostTime)
{
    //排序Times,此处省略
    if(memoCostTime[n-1] >= 0)
    {
        return memoCostTime[n-1];
    }
    
    //记录结果
    if (n <= 2)
    {
        memoCostTime[n-1] = Times[n-1];
        return Times[n-1];
    }
    
    memoCostTime[n-1] = min(memoCrossBridge(n-1,memoCostTime) + Times[0] + Times[n-1],
                Times[0] + 2 * Times[1] + Times[n-1] + memoCrossBridge(n-2,memoCostTime)); 
    return memoCostTime[n-1];
}

//备忘录式的方法
int record(int n)
{
    int *memoCostTime = new int [n];
    for (int i = 0; i < n; i++)
    {
        memoCostTime[i] = -1;
    }
    return memoCrossBridge(n, memoCostTime);
}


int main() {
    std::cout << "备忘录式的方法:" << record(4);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值