天天看点

《算法设计编程实验:大学程序设计课程与竞赛训练教材》——1.1 机理分析法的实验范例

根据客观事物的特性,分析其内部的机理,弄清关系,在适当抽象的条件下,得到可以描述事物属性的数学工具。

《算法设计编程实验:大学程序设计课程与竞赛训练教材》——1.1 机理分析法的实验范例

经过数学分析,如果能够抽象出ad hoc类问题的内在规律,则可以采用机理分析法建立数学模型,然后根据模型的原理对应到算法,编程实现,通过执行算法得到问题解,如图1.1-1所示。

机理分析法的核心是数学建模,即使用适当的数学思想建立起模型;或者提取问题中的有效信息,用简明的方式表达其规律。需要注意的是:

1)选择的模型必须尽量多地体现问题的本质特征。但这并不意味着模型越复杂越好,累赘的信息会影响算法效率。

2)模型的建立不是一个一蹴而就的过程,而是要经过反复地检验和修改,在实践中不断完善。

3)数学模型通常有严格的格式,但程序编写形式可不拘一格。

机理分析法是一个复杂的数据抽象过程。我们要善于透视问题的本质,寻找突破口,进而选择适当的模型。模型的构造过程可以帮助我们认识问题,不同的模型从不同的角度反映问题,可以引发不同的思路,起到引导发散思维的作用。但认识问题的最终目的是解决问题,模型的固有性质虽可帮我们建立算法,其优劣也可通过时空复杂度等指标来分析和衡量,但最终还是以程序的运行结果为标准。所以模型不是一成不变的,同样要通过各种技术不断优化。模型的产生虽然是人脑思维的产物,但它仍然是客观事物在人脑中的反映。所以要培养良好的建模能力,还必须依靠在平时的学习中积累丰富的知识和经验。

下面举两个实验范例。

【1.1.1 factstone benchmark】

【问题描述】

amtel已经宣布,到2010年,它将发行128位计算机芯片;到2020年,它将发行256位计算机;等等,amtel坚持每持续十年将其字大小翻一番的战略。(amtel于2000年发行了64位计算机,在1990年发行了32位计算机,在1980年发行了16位计算机,在1970年发行了8位计算机,并首先在1960年发行了4位计算机。)

amtel将使用新的标准检查等级(factstone)来宣传其新芯片大大提高的能力。factstone等级被定义为这样的最大整数n,使得n!可以表示为一个计算机字中的无符号整数(比如1960年的4位计算机可表示3!=6,而不能表示4!=24)。

给出一个年份1960≤y≤2160,amtel最近发布的芯片的factstone等级是什么?

输入:

给出若干测试用例。每个测试用例一行,给出年份y。在最后一个测试用例后,给出包含0的一行。

输出:

对于每个测试用例,输出一行,给出factstone等级。

《算法设计编程实验:大学程序设计课程与竞赛训练教材》——1.1 机理分析法的实验范例

试题来源:waterloo local 2005.09.24

在线测试地址:poj 2661,uva 10916

试题解析

对于给定的年份,先求出当年amtel处理器的字大小,然后计算出最大的n的值,使得n!成为一个符合字的大小的无符号整数。

在1960年,字的大小是4位,以后每十年字的大小翻一番,这就意味着,y年字的位数为k=22+y-196010。能放在k位中最大的无符号整数是2k-1。如果n!为不大于2k-1的最大正整数,则n为y年芯片的factstone等级。计算方法有两种:

方法1:直接求不大于2k-1的最大正整数n!,这种方法极容易溢出且速度慢。

方法2:采用对数计算,即根据log2n!=log2n+log2(n-1)+…+log21≤log2(2k-1)计算y年字的位数k,累加log2i(i从1出发,每次加1),直到数字超过k为止。此时,i-1即为factstone等级。

程序清单

【1.1.2 bridge】

n个人要在晚上过桥,在任何时候最多两人一组过桥,每组要有一只手电筒。在这n个人中只有一只手电筒可以用,因此要安排以某种往返的方式来返还手电筒,使得更多的人可以过桥。

每个人的过桥速度不同,每组的速度由速度较慢的成员所决定。请确定一个策略,让n个人用最少的时间过桥。

输入的第一行给出n,接下来的n行给出每个人的过桥时间,不会超过1000人,且没有人的过桥时间超过100秒。

输出的第一行给出所有n个人过桥的总的秒数,接下来的若干行给出实现策略。每行包含一个或两个整数,表示组成一组过桥的一个人或两个人(每个人用其在输入中给出的过桥所用的时间来标识。虽然许多人的过桥时间相同,但即使有混淆,对结果也没有影响)。这里要注意的是过桥也有方向性,因为要返还手电筒让更多的人通过。如果用时最少的策略有多个,则任意一个都可以。

《算法设计编程实验:大学程序设计课程与竞赛训练教材》——1.1 机理分析法的实验范例

试题来源:waterloo local 2000.09.30

在线测试地址:poj 2573,zoj 1877,uva 10037

稍动脑筋,便可以得出一个简单的逻辑:要使得n个人用最少的时间过桥,慢的成员必须借助快的成员传递手电筒。

由于一次过桥最多两人且手电筒需要往返传递,因此以两个成员过桥为一个分析单位,计算过桥时间。我们按过桥时间递增的顺序将n个成员排序。设当前序列中,

a是最快的人,b是次快的人,a和b是序列首部的两个元素。

a是最慢的人,b是次慢的人,a和b是序列尾部的两个元素。

有两种过桥方案:

方案1:用最快的成员a传递手电筒帮助最慢的a和b过桥。

如果带一个最慢的成员,则所用的时间是a+a(a表示最快和最慢的两个成员到对岸所需的时间,而a是最快的成员返回所需的时间)。显然带两个最慢的成员所用的时间是2*a+a+b。

方案2:用最快的成员a和次快的成员b传递手电筒帮助最慢的a和b过桥。

步骤1:a和b到对岸,所用时间为b。

步骤2:a返回,将手电筒给最慢的a和b,所用时间为a。

步骤3:a和b到对岸,所用时间为a;到对岸后,他们将手电筒交给b。

步骤4:b需要返回原来的岸边,因为要交还手电筒,所需时间为b。

所以,需要的总时间为2*b+a+a。

显然,最慢的a和b要用最少的时间过桥,只能借助a或者a和b传递手电筒过桥,其他方法都会增加过桥时间。哪一种过桥方案更有效?比较一下就行了:

如果(2a+a+b<2b+a+a),则采用第1种方案,即用最快的成员a传递手电筒;否则采用第2种方案,即用最快的成员a和次快的成员b传递手电筒(2a+a+b<2b+a+a等价于b+a<2*b)。

我们每次帮助最慢的两个成员过桥(n-=2),累计每个最佳过桥方案的时间。最后产生两种可能情况:

1)对岸剩下2个队员(n==2),全部过桥,即累计时间为b。

2)对岸剩下3个队员(n==3),用最快的成员传递手电筒,帮助最慢的成员过桥,然后与次慢的成员一起过桥,即累计时间为a+a+b。

继续阅读