问题描述:在漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的桥边。如果不借助手电筒的话,大家是无论如何也不敢过桥去的。不幸的是,N个人一共只带了一只手电筒,而桥窄得只够让两个人同时过。如果各自单独过桥的话,N人所需要的时间已知;而如果两人同时过桥,所需要的时间就是走得比较慢的那个人单独行动时所需的时间。问题是,如何设计一个方案,让这N人尽快过桥。假设N <= 1000。

思路:假设N个旅行者的过桥时间分别为(已排序){T1, T2, T3, T4 ... Tn},N个旅行者过桥的最快时间为sum。 从简单入手,如果N = 1, sum = T1;如果N = 2,  sum = max(T1, T2);如果N = 3, sum = T1+T2+T3。如果N > 3,考虑最慢和次慢两个人的过桥方法。共有两种方案。

第一种,最快和次快的人先过去(用时T[1]),然后最快的人回来(用时T[0]),接着最慢和次慢的人过去(用时T[n-1]),最后次快的人回来(用时T[1])。整理后为T[0] + T[1] + T[1] + T[n-1]。

第二种,最快和最慢的过去(用时T[n-1]),然后最快的回来(用时T[0]),接着最快和次慢的人过去(用时T[n-2]),最后次快的人回来(用时T[0])。整理后为T[0] + T[0] + T[n-1] + T[n-2]。

选用时少的方案,这样旅行者的数量减少了两个,递归求解即可。下面给出代码。

参考代码:

//函数功能: 过河问题递归求解
//函数参数: T为旅行者的过河时间,n为旅行者个数
//返回值:   最快过河时间
int CrossRiver(int *T, int n)
{if(n == 2)       //剩两个人return T[1];else if(n == 3)  //剩三个人return T[0] + T[1] + T[2];else{int t1 = T[0] + T[1] + T[1] + T[n-1];   //方案1int t2 = T[0] + T[0] + T[n-1] + T[n-2]; //方案2int t = t1 > t2 ? t2 : t1;return CrossRiver(T, n - 2) + t;}
}
//函数功能: 过河问题
//函数参数: T为旅行者的过河时间,n为旅行者个数
//返回值:   最快过河时间
int CrossRiverProblem(int *T, int n)
{if(n == 1)         //一个旅行者return T[0];   else if(n == 2)    //两个旅行者return T[0] > T[1] ? T[0]: T[1];else               //多个,递归求解{sort(T, T + n);//排个序return CrossRiver(T, n);}
}

下面给出非递归解法,效率会高一点。

//函数功能: 过河问题
//函数参数: T为旅行者的过河时间,n为旅行者个数
//返回值:   最快过河时间
int CrossRiverProblem(int *T, int n)
{if(n == 1)         //一个旅行者return T[0];   else if(n == 2)    //两个旅行者return T[0] > T[1] ? T[0]: T[1];else               //多个{sort(T, T + n);//排个序int sum = 0;while(1){if(n == 2)      //剩两个人{sum += T[1];break;}else if(n == 3) //剩三个人{sum += T[0] + T[1] + T[2];break;}else{int t1 = T[0] + T[1] + T[1] + T[n-1];   //方案1int t2 = T[0] + T[0] + T[n-1] + T[n-2]; //方案2sum += (t1 > t2 ? t2 : t1);n -= 2;}}return sum;}
}

本人享有博客文章的版权,转载请标明出处 http://blog.csdn.net/wuzhekai1985

解题笔记(39)——过河问题相关推荐

  1. 模拟六:STEMA 考试选择题模拟练习试卷(中级组)及答案 + 自我解题笔记

    模拟一:STEMA 考试选择题模拟练习试卷(初级组)及答案 + 自我解题笔记 模拟二:STEMA 考试选择题模拟练习试卷(中级组)及答案 + 解题后期更新 模拟三:STEMA 考试选择题模拟练习试卷( ...

  2. 模拟四:STEMA 考试选择题模拟练习试卷(中级组)及答案 + 自我解题笔记

    模拟一:STEMA 考试选择题模拟练习试卷(初级组)及答案 + 自我解题笔记 模拟二:STEMA 考试选择题模拟练习试卷(中级组)及答案 + 解题后期更新 模拟三:STEMA 考试选择题模拟练习试卷( ...

  3. 模拟三:STEMA 考试选择题模拟练习试卷(初级组)及答案 + 自我解题笔记

    模拟一:STEMA 考试选择题模拟练习试卷(初级组)及答案 + 自我解题笔记 模拟二:STEMA 考试选择题模拟练习试卷(中级组)及答案 + 解题后期更新 模拟三:STEMA 考试选择题模拟练习试卷( ...

  4. 模拟一:STEMA 考试选择题模拟练习试卷(初级组)及答案 + 自我解题笔记

    模拟一:STEMA 考试选择题模拟练习试卷(初级组)及答案 + 自我解题笔记 模拟二:STEMA 考试选择题模拟练习试卷(中级组)及答案 + 解题后期更新 模拟三:STEMA 考试选择题模拟练习试卷( ...

  5. 处理器在实施任务切换时的操作——《x86汇编语言:从实模式到保护模式》读书笔记39

    处理器在实施任务切换时的操作--<x86汇编语言:从实模式到保护模式>读书笔记39 处理器可以通过以下四种方法实施任务切换: 1. call指令或者jmp指令的操作数是GDT内的某个TSS ...

  6. 解题笔记(15)——几个栈和递归的问题

    本文介绍了几个栈和递归的问题,当然递归的本质就是栈.这些问题网上都能找到解答,自己思考并实现了一下,供网友参考. 问题1:跳台阶问题.具体描述,一个台阶总共有n级,如果一次可以跳1级,也可以跳2级.求 ...

  7. 模拟五:STEMA 考试选择题模拟练习试卷(初级组)及答案 + 自我解题笔记

    模拟一:STEMA 考试选择题模拟练习试卷(初级组)及答案 + 自我解题笔记 模拟二:STEMA 考试选择题模拟练习试卷(中级组)及答案 + 解题后期更新 模拟三:STEMA 考试选择题模拟练习试卷( ...

  8. 【1错笔记】过河问题——动态规划的经典线性模型(3000字超详细手写解题)

    题目: 在一个夜黑风高的晚上,有n(n <= 50)个小朋友在桥的这边,现在他们需要过桥,但是由于桥很窄,每次只允许不大于两人通过,他们只有一个手电筒,所以每次过桥的两个人需要把手电筒带回来,i ...

  9. Python解题 - NOIP2005 青蛙过河

    本题解经过热心网友的指正,已经更新,问哥为之前的武断向大家道歉.此题解仅供参考,感谢大家的监督与建议. 题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很 ...

最新文章

  1. android:showAsAction=never报错
  2. 用openssl跟Gmail的smtp对话(一)
  3. CSS之使用display:inline-block布局
  4. mysql查看当前连接数
  5. SpringAOP02 自定义注解
  6. java scanner_Java Scanner match()方法与示例
  7. 函数式接口 lambda表达式 方法引用
  8. 反向微分运放电路波形_做到这三步,轻松实现运放电路稳定性
  9. 如何在sh的字符串中包含换行符?
  10. ie8 升级页面html,IE8怎么升级到IE11 IE浏览器怎么升级
  11. [转]BT1120接口及协议
  12. 感谢蜂窝教育,四个月的学习,让我改变了
  13. UserScript 改变网页颜色
  14. SQL server修改字段名,属性
  15. 我们不应该歧视任何的编程语言,因为他们都是萌娘
  16. BZOJ#4816. [Sdoi2017]数字表格
  17. 树形导航栏(折叠)(jquery)
  18. 计算机密码技术发展,密码技术的分类
  19. 计算机病毒的常用方法,常用计算机检测病毒的方法
  20. Quoted-Printable编码原理及代码实现

热门文章

  1. 浅谈如何开一场 Chat
  2. 面试题 17.16. 按摩师(简单题)
  3. 优秀的JavaScript模块是怎样炼成的
  4. Linux下system () 函数详解简介
  5. java转go之初体验(一)
  6. 雨听 | 英语学习笔记(九)~作文范文:父母应该送孩子出国留学吗?
  7. Anconda 安装
  8. 帮忙写一份2022年医院信息科年度工作汇报
  9. 【Python使用】Python解析JSON数据的基本方法/用MATLAB解析json格式数据
  10. FFmpeg给视频添加水印