目录
前言
数学源自于生活,所以数学就是为了解决生活中的问题而出现的,故而算法就是更快更高效率的解决问题.下面说一我在阅读陈小玉老师的《趣味算法》中那些有趣的例子
一、国王的棋盘
有一个古老的传说,一位国王的女儿不幸落水,水中有很多鳄鱼,国王情急之下下令:“谁能把公主救上来,就把女儿嫁给他。”很多人纷纷退让,一个勇敢的小伙子挺身而出,冒着生命危险把公主救了上来,国王一看是个穷小子,想要反悔,说:“除了女儿,你要什么都可以。”小伙子说:“好吧,我只要一棋盘的麦子。您在第1个格子里放1粒麦子,在第2个格子里放2粒,在第3个格子里放4粒,在第4个格子里放8粒,以此类推,每一个格子里麦子的粒数都是前一格子里麦子粒数的两倍。把这64个格子放满了就我就要这么多。国王听后哈哈大笑,觉得小伙子的要求很容易满足,满口答应。结果发现,把全国的麦子都拿来,也填不完这64个格孔.....国王无奈,只好把女儿嫁给了这个小伙子。
。
二、提出问题
1.棋盘上的64个格子究竟需要放多少粒麦子?
把每个格子里需要放的麦 子粒数加起来,总和为S,则: 把每个格子里需要放的麦子粒数加起来,总和为S,则:
2.1 问题分析
对式①等号的两边乘以2,等式仍然成立:
用式②减去式①,得: 用式2减去式1,得:
据专家统计,每颗麦粒的平均重量约41.9毫克,这些麦粒的总重量为: 据专家统计,每颗麦粒的平均重量约41.9毫克,这些麦粒的总重量为:
18 446 744 073 709 551 615 x41.9= 772918 576 688 430212 668.5 (毫克)
≈7729000(亿千克)
全世界人口按77亿计算,每人差不多可以分得
100 000千克(即100吨) !
2.2 爆炸函数
我们称这样的函数为爆炸增量函数。想一想,如果算法的时间复杂度是0(2”)会怎样?随着n的增长,算法会不会"爆掉"?我们经常见到有些算法调试没问题,运行一段时间也没问题,但在关键的时候宕机(shutdown)。例如在线考试系统,50人考试没问题,100人考 试也没问题,但如果全校10000人考试就可能宕机。
数阶增量随着x的增加而急剧增加,而对数阶增长缓慢。它们之间的关系如下:
0(1)< O(logn)< O(n)< O(nlogn) < O(n2)< O(n3)< 0(2") < O(n!)< O(n")
在设计算法时,我们要注意算法复杂度增量的问题,尽量避免爆炸级增量。
题目分析完之后就实际操作一下
2.3 举例代码
如下
program ex1543; var n,m,t,w,i:integer; a,b:array[1..200] of integer; procedure gjc; var i:integer; begin for i:=1 to t do a[i]:=a[i]*2; t:=1; while a[t]<>0 do begin a[t+1]:=a[t+1]+a[t] div 1000; a[t]:=a[t] mod 1000; inc(t); end; dec(t); end; procedure gjj; var i:integer; begin for i:=1 to t do b[i]:=b[i]+a[i]; w:=1; while b[w]<>0 do begin b[w+1]:=b[w+1]+b[w] div 1000; b[w]:=b[w] mod 1000; inc(w); end; dec(w); end; begin readln(n,m); fillchar(a,sizeof(a),0); fillchar(b,sizeof(b),0); a[1]:=1;t:=1; w:=1; if n=1 then b[1]:=1; for i:=1 to m-1 do begin gjc; if i>=n-1 then gjj; end; write(b[w]) ; if w>1 then write(','); for i:=w-1 downto 1 do begin if b[i]<10 then write('00'); if (b[i]>=10) and (b[i]<100) then write('0'); write(b[i]); if i<>1 then write(',') end; end.
总结
国王的棋盘一个有趣的故事,希望和大家一起学习进步,每天一个有趣的小故事,收获不一样的知识