2009年9月刊《程序员》算法题之我见——思索之一
2009-09-18 09:04
609 查看
本系列文章目录
2009年9月刊《程序员》算法题之我见——思索之一
2009年9月刊《程序员》算法题之我见——思索之二
2009年9月刊《程序员》算法题之我见——思索之三
2009年9月刊《程序员》算法题之我见——思索之一
笔者业余时间喜欢研究一些算法,也经常的阅读各类计算机杂志并对其中的算法题研究考量一番
翻阅了2009年9月刊《程序员》,其中的一道算法题吸引了我。虽然至今还没有理解透,但是也小有心得。拿在这个和大家交流一番。
先把题目复述一遍。
如何为实习生安排座位
有道最近招聘了一批实习生,给他们安排座位时遇到一个有趣的问题。办公室有N排,每排有M个座位。为了方便实习生和全职员工更好的交流,安排座位时,我们不让任何2个实习生座位水平、竖直、或者对角线相邻。求满足安排方案的总数。
文章最后给了一个测试条件:M=15,N=150,每排4人,求方案总数。
文章给了3个解决方案。可惜本人愚笨,没有能力参悟,只有自己一个人抽丝剥茧,层层深入,期待有朝一日,能够理解透。
为了描述方便,一共有N排,每排M个座位,每排安排P个实习生
问题一,M=15,则P最大为多少?毫无疑问P最大为8人。
而且这8人只有一种安排法
如图
示意图,红色表示实习生
问题二,M=S,P最大为多少?
参照问题一,可知,当S为奇数时,P最大为(S+1)/2;当S为偶数时,P最大为S/2
问题三,M=15,N=1,P=4,安排方案总数?
用一个函数表示安排总数F(M,P),其中M为座位数,P为人数,返回的是方案总数
不难理解,本题就是计算F(15,4)
而且,F还满足递归,即
F(15,4)=F(13,3)+F(12,3)+F(11,3)……+F(1,3)
那么,很容易的,该函数马上就能用代码表示出来
Private Function F(ByVal M As Integer, ByVal P As Integer) As Integer
If P <= 0 OrElse M <= 0 Then Return 0
If P = 1 Then Return M
If P * 2 = M + 1 Then Return 1
If P * 2 > M + 1 Then Return 0
Dim i As Integer, S As Integer, tS As Integer
S = 0
For i = M - 2 To 1 Step -1
tS = F(i, P - 1)
If tS = 0 Then
Return S
Else
S += tS
End If
Next
Return S
End Function
经计算,F(15,4)=495,所以本问题的解为495
问题四,M=15,N=2,P=4,安排方案总数?
由问题三可知,每排的可能性有495种,是不是意味着两排就一定是4952种呢?很显然,不是的。因为这两排彼此之间还互相有影响。下面举两个例子
例子一:下面这个情况就不符合题意
示意图,红色表示实习生
例子二:下面这个情况就符合题意
示意图,红色表示实习生
可见,对于第一行的每种情况,第二行并不完全都符合,还得分情况考虑。如果执着于分情况考虑,未免工作量太大。
仔细观察例子二情况,突然发现如果将两排压缩为一排的话,正好是问题一的图。而例子一压缩为一排的话,就不是问题一的图。
于是,基于此,提出一个假设。
该问题的每一个解都能压缩成问题一的图,而本题的每一个不成立的解都压不成问题一的解。也就是说,把问题一的图中随机选出四个位置作为第一排的情况,则另外四个位置就是第二排的情况。
则本题的答案就很明了了,C(8,4)=70种,C表示组合函数,这里就不详细解释了。
问题五:M=15,N=150,P=4,求方案总数
这是一开始的测试情况。也是问题四的延伸。这样想,第一排的位置定下来的话,第二排就一种情况。这是问题四的解。同时,第三排也就一种情况,和第一排相同,第四排受第三排的影响,也是一种情况,和第二排相同。以此类推,本题的解就是问题四的解C(8,4)=70种。
暂且思考到这儿,先把测试的情况计算出来。这个思路对其他的情况有着参考的作用。日后再撰文,与大家交流。
2009年9月刊《程序员》算法题之我见——思索之一
2009年9月刊《程序员》算法题之我见——思索之二
2009年9月刊《程序员》算法题之我见——思索之三
2009年9月刊《程序员》算法题之我见——思索之一
笔者业余时间喜欢研究一些算法,也经常的阅读各类计算机杂志并对其中的算法题研究考量一番
翻阅了2009年9月刊《程序员》,其中的一道算法题吸引了我。虽然至今还没有理解透,但是也小有心得。拿在这个和大家交流一番。
先把题目复述一遍。
如何为实习生安排座位
有道最近招聘了一批实习生,给他们安排座位时遇到一个有趣的问题。办公室有N排,每排有M个座位。为了方便实习生和全职员工更好的交流,安排座位时,我们不让任何2个实习生座位水平、竖直、或者对角线相邻。求满足安排方案的总数。
文章最后给了一个测试条件:M=15,N=150,每排4人,求方案总数。
文章给了3个解决方案。可惜本人愚笨,没有能力参悟,只有自己一个人抽丝剥茧,层层深入,期待有朝一日,能够理解透。
为了描述方便,一共有N排,每排M个座位,每排安排P个实习生
问题一,M=15,则P最大为多少?毫无疑问P最大为8人。
而且这8人只有一种安排法
如图
问题二,M=S,P最大为多少?
参照问题一,可知,当S为奇数时,P最大为(S+1)/2;当S为偶数时,P最大为S/2
问题三,M=15,N=1,P=4,安排方案总数?
用一个函数表示安排总数F(M,P),其中M为座位数,P为人数,返回的是方案总数
不难理解,本题就是计算F(15,4)
而且,F还满足递归,即
F(15,4)=F(13,3)+F(12,3)+F(11,3)……+F(1,3)
那么,很容易的,该函数马上就能用代码表示出来
Private Function F(ByVal M As Integer, ByVal P As Integer) As Integer
If P <= 0 OrElse M <= 0 Then Return 0
If P = 1 Then Return M
If P * 2 = M + 1 Then Return 1
If P * 2 > M + 1 Then Return 0
Dim i As Integer, S As Integer, tS As Integer
S = 0
For i = M - 2 To 1 Step -1
tS = F(i, P - 1)
If tS = 0 Then
Return S
Else
S += tS
End If
Next
Return S
End Function
经计算,F(15,4)=495,所以本问题的解为495
问题四,M=15,N=2,P=4,安排方案总数?
由问题三可知,每排的可能性有495种,是不是意味着两排就一定是4952种呢?很显然,不是的。因为这两排彼此之间还互相有影响。下面举两个例子
例子一:下面这个情况就不符合题意
例子二:下面这个情况就符合题意
可见,对于第一行的每种情况,第二行并不完全都符合,还得分情况考虑。如果执着于分情况考虑,未免工作量太大。
仔细观察例子二情况,突然发现如果将两排压缩为一排的话,正好是问题一的图。而例子一压缩为一排的话,就不是问题一的图。
于是,基于此,提出一个假设。
该问题的每一个解都能压缩成问题一的图,而本题的每一个不成立的解都压不成问题一的解。也就是说,把问题一的图中随机选出四个位置作为第一排的情况,则另外四个位置就是第二排的情况。
则本题的答案就很明了了,C(8,4)=70种,C表示组合函数,这里就不详细解释了。
问题五:M=15,N=150,P=4,求方案总数
这是一开始的测试情况。也是问题四的延伸。这样想,第一排的位置定下来的话,第二排就一种情况。这是问题四的解。同时,第三排也就一种情况,和第一排相同,第四排受第三排的影响,也是一种情况,和第二排相同。以此类推,本题的解就是问题四的解C(8,4)=70种。
暂且思考到这儿,先把测试的情况计算出来。这个思路对其他的情况有着参考的作用。日后再撰文,与大家交流。
相关文章推荐
- 2009年9月刊《程序员》算法题之我见——思索之二
- 2009年9月刊《程序员》算法题之我见——思索之三
- 程序员一定要了解哪十大算法
- 程序员必须知道的十大基础实用算法
- 程序员必须知道的10大基础实用算法及其讲解(Javascript代码实现)
- 程序员编程艺术:第三章续、Top K算法问题的实现
- 程序员必须知道的10大基础实用算法及其讲解
- 程序员面试题精选100题(03)-子数组的最大和[算法]
- 程序员必须知道的10大基础实用算法及其讲解
- 测测您的能力:微软程序员测试题(算法)
- 寒假挑战PythonTip(一人一python)总结——算法是程序的灵魂,程序员的心法
- 程序员面试题精选100题(63)-数组中三个只出现一次的数字[算法]
- 博客园电子期刊2009年10月刊发布啦
- 程序员如何快速准备面试中的算法
- 程序员应该熟练掌握这些算法
- 【算法设计与数据结构】为何程序员喜欢将INF设置为0x3f3f3f3f?
- 如何思索算法(三)-动态规划
- 程序员的算法趣题Perl版(四)
- 程序员懂算法玩“淮安掼蛋”是否更有优势?