順推法
倒推法的逆過程就是順推法,即由邊界條件出發,通過遞推關系式推出後項值,再由後項值按遞推關系式推出再後項值......,依次遞推,直至從問題初始陳述向前推進到這個問題的解為止。
實數數列:一個實數數列共有N項,已知
ai=(a
i-1-a
i+1)/2+d, (1<i<N)(N<60)
鍵盤輸入N,d,a
1,a
n,m,輸出a
m 輸入數據均不需判錯。
算法分析:
分析該題,對公式:
A
i=(A
i-1-A
i+1)/2+d (1<i<N) (n<60)
作一翻推敲,探討其數字變換規律。不然的話會無從下手。
令 X=A
2 s
2[i]=(p
i,Q
i,R
i)表示A
i=P
iX+Q
iD+R
iA
1 我們可以根據
A
i=A
i-2-2A
i-1+2D
=P
iX+Q
iD+R
iA
1 推出公式
P
iX+Q
iD+R
iA
1=(P
i-2-2P
i-1)X+(Q
i-2-2Q
i-1+2)D+(R
i-2-2R
i-1)A
1 比較等號兩端X,D和A1的系數項,可得
P
i=P
i-2-2P
i-1 Q
i=Q
i-2-2Q
i-1+2
R
i=R
i-2-2R
i-1 加上兩個邊界條件
P
1=0 Q
1=0 R
1=1 (A
1=A
1)
P
2=1 Q
2=0 R
2=0 (A
2=A
2)
根據Pi、Qi、Ri的遞推式,可以計算出
S
2[1]=(0,0,1);
S
2[3]=(-2,2,1);
S
2[4]=(5,-2,-2);
S
2[5]=(-12,8,5);
...................
S
2[i]=(P
i,Q
i,R
i);
...................
S
2[N]=(P
N,Q
N,R
N);
有了上述基礎,AM便不難求得。有兩種方法:
1、由於A
N、A
1和P
N、Q
N、R
N已知,因此可以先根據公式:
A
2=A
N-Q
ND-R
NA
1/P
N 求出A
2。然後將A
2代入公式
A
3=A
1-2A
2+2D
求出A
3。然後將A
3代入公式
A
4=A
2-2A
3+2D
求出A
4。然後將A
4代入公式
............................
求出A
i-1。然後將A
i-1代入公式
A
i=A
i-2-2A
i-1+2D
求出A
i。依此類推,直至遞推至A
M為止。
上述算法的缺陷是由於A2是兩數相除的結果,而除數PN遞增,因此精度誤差在所難免,以後的遞推過程又不斷地將誤差擴大,以至當M超過40時,求出的AM明顯徧離正確值。顯然這種方法簡單但不可靠。
2、我們令A
2=A
2,A
3=X,由S
3[i]=(P
i,Q
i,R
i)表示A
i=P
iX+Q
iD+R
iA
2 (i>=2) 可計算出:
S
3[2]=(0,0,1)=S
2[1];
S
3[3]=(1,0,0)=S
2[2];
S
3[4]=(-2,2,1)=S
2[3];
S
3[5]=(5,-2-2)=S
2[4];
......................
S
3[i]=(..........)=S
2[i-1];
.....................
S
3[N]=(..........)=S
2[N-1];
再令A
3=A
3,A
4=X,由S
4[i]=(p
i,Q
i,R
i)表示A
i=P
iX+Q
iD+R
iA
3 (i>=3) 可計算得出:
S
4[3]=(0,0,1)=S
3[2]=S
2[1];
S
4[4]=(1,0,0)=S
3[3]=S
2[2];
S
4[5]=(-22,1)=S
3[4]=S
2[3];
..........................
S
4[i]=(...........)=S
3[i-1]=S
2[i-2];
.......................
S
4[N]=(...........)=S
3[N-1]=S
2[N-2];
依此類推,我們可以發現一個有趣的式子:
A
N=P
N-i+2*A
i+Q
N-i+2*D+R
N-i+2*A
i-1, 即
A
i=(A
N-Q
N-i+2*D-R
N-i+2*A
i-1)/P
N-i+2 我們從已知量A
1和A
N出發,依據上述公式順序遞推A
2、A
3、...、A
M.由於P
N-i+2遞減,因此最後得出的A
M要比第一種算法趨於精確。
程序代碼如下:
program ND1P4;
const
maxn =60;
var
n,m,i :integer;
d :real;
list :array[1..maxn] of real; {list[i]-------對應ai}
s :array[1..maxn,1..3] of real; {s[i,1]--------對應Pi}
{s[i,2]--------對應Qi}
{s[i,3]--------對應Ri}
procedure init;
begin
write('n m d =');