Ⅰ 象棋&米粒-迭代法
这里引用一个大家从小就听过的小故事。
传说,印度的舍罕国王打算重赏国际象棋的发明人——大臣西萨·班·达依尔。这位聪明的大臣跪在国王面敢说:“陛下,请你在这张棋盘的第一个小格内,赏给我一粒麦子,在第二个小格内给两粒,在第三个小格内给四粒,照这样下去,每一小格内都比前一小格加一倍。陛下啊,把这样摆满棋盘上所有64格的麦粒,都赏给您的仆人吧?”国王说:“你的要求不高,会如愿以偿的”。说着,他下令把一袋麦子拿到宝座前,计算麦粒的工作开始了。……还没到第二十小格,袋子已经空了,一袋又一袋的麦子被扛到国王面前来。但是,麦粒数一格接一格地增长得那样迅速,很快看出,即使拿出来全印度的粮食,国王也兑现不了他对象棋发明人许下的语言。
这个故事中的计算麦粒的方法,在数学上是有对应方法的,这也正是这篇文章要讲的概念——迭代法(Iterative Method)。
那么到底什么是迭代法呢?
简单来说,迭代法就是不断地用旧的变量值,递推计算新的变量值。
我们回到这个国际象棋的故事,大臣要求每一格的麦子都是前一格的两倍,那么前一格里麦子的数量就是旧的变量值,我们可以先记作 Xn-1 ;而当前格子里麦子的数量就是新的变量值,我们记作 Xn 。这两个变量的递推关系如下👇
有编程经验的人很容易就想到,迭代的思想可以通过计算机语言中的循环语句来实现。计算机本身就很适合做重复性的工作,我们可以通过循环语句,让计算机重复执行迭代中的递推步骤,然后推导出变量的最终值。
Ⅱ 编程求麦粒的数量
这里我用C语言实现一下这个迭代过程。
#include <stdio.h>
long getNumberOfWheat(int grid);
long getNumberOfWheat(int grid) {
int i = 2;
long sum = 0; //麦子的总数
long numberOfWheatInGrid = 0; //当前格子上麦子的数量
numberOfWheatInGrid = 1;
sum += numberOfWheatInGrid;
for (; i <= grid; i++) {
numberOfWheatInGrid *