解题笔记(39)——过河问题
问题描述:在漆黑的夜里,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)——过河问题相关推荐
- 模拟六:STEMA 考试选择题模拟练习试卷(中级组)及答案 + 自我解题笔记
模拟一:STEMA 考试选择题模拟练习试卷(初级组)及答案 + 自我解题笔记 模拟二:STEMA 考试选择题模拟练习试卷(中级组)及答案 + 解题后期更新 模拟三:STEMA 考试选择题模拟练习试卷( ...
- 模拟四:STEMA 考试选择题模拟练习试卷(中级组)及答案 + 自我解题笔记
模拟一:STEMA 考试选择题模拟练习试卷(初级组)及答案 + 自我解题笔记 模拟二:STEMA 考试选择题模拟练习试卷(中级组)及答案 + 解题后期更新 模拟三:STEMA 考试选择题模拟练习试卷( ...
- 模拟三:STEMA 考试选择题模拟练习试卷(初级组)及答案 + 自我解题笔记
模拟一:STEMA 考试选择题模拟练习试卷(初级组)及答案 + 自我解题笔记 模拟二:STEMA 考试选择题模拟练习试卷(中级组)及答案 + 解题后期更新 模拟三:STEMA 考试选择题模拟练习试卷( ...
- 模拟一:STEMA 考试选择题模拟练习试卷(初级组)及答案 + 自我解题笔记
模拟一:STEMA 考试选择题模拟练习试卷(初级组)及答案 + 自我解题笔记 模拟二:STEMA 考试选择题模拟练习试卷(中级组)及答案 + 解题后期更新 模拟三:STEMA 考试选择题模拟练习试卷( ...
- 处理器在实施任务切换时的操作——《x86汇编语言:从实模式到保护模式》读书笔记39
处理器在实施任务切换时的操作--<x86汇编语言:从实模式到保护模式>读书笔记39 处理器可以通过以下四种方法实施任务切换: 1. call指令或者jmp指令的操作数是GDT内的某个TSS ...
- 解题笔记(15)——几个栈和递归的问题
本文介绍了几个栈和递归的问题,当然递归的本质就是栈.这些问题网上都能找到解答,自己思考并实现了一下,供网友参考. 问题1:跳台阶问题.具体描述,一个台阶总共有n级,如果一次可以跳1级,也可以跳2级.求 ...
- 模拟五:STEMA 考试选择题模拟练习试卷(初级组)及答案 + 自我解题笔记
模拟一:STEMA 考试选择题模拟练习试卷(初级组)及答案 + 自我解题笔记 模拟二:STEMA 考试选择题模拟练习试卷(中级组)及答案 + 解题后期更新 模拟三:STEMA 考试选择题模拟练习试卷( ...
- 【1错笔记】过河问题——动态规划的经典线性模型(3000字超详细手写解题)
题目: 在一个夜黑风高的晚上,有n(n <= 50)个小朋友在桥的这边,现在他们需要过桥,但是由于桥很窄,每次只允许不大于两人通过,他们只有一个手电筒,所以每次过桥的两个人需要把手电筒带回来,i ...
- Python解题 - NOIP2005 青蛙过河
本题解经过热心网友的指正,已经更新,问哥为之前的武断向大家道歉.此题解仅供参考,感谢大家的监督与建议. 题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很 ...
最新文章
- android:showAsAction=never报错
- 用openssl跟Gmail的smtp对话(一)
- CSS之使用display:inline-block布局
- mysql查看当前连接数
- SpringAOP02 自定义注解
- java scanner_Java Scanner match()方法与示例
- 函数式接口 lambda表达式 方法引用
- 反向微分运放电路波形_做到这三步,轻松实现运放电路稳定性
- 如何在sh的字符串中包含换行符?
- ie8 升级页面html,IE8怎么升级到IE11 IE浏览器怎么升级
- [转]BT1120接口及协议
- 感谢蜂窝教育,四个月的学习,让我改变了
- UserScript 改变网页颜色
- SQL server修改字段名,属性
- 我们不应该歧视任何的编程语言,因为他们都是萌娘
- BZOJ#4816. [Sdoi2017]数字表格
- 树形导航栏(折叠)(jquery)
- 计算机密码技术发展,密码技术的分类
- 计算机病毒的常用方法,常用计算机检测病毒的方法
- Quoted-Printable编码原理及代码实现