最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++遞推算法的具體使用

 更新時(shí)間:2026年02月27日 15:26:36   作者:ZZZZYYYPPP  
遞推算法通過已知初始條件和遞推關(guān)系,逐步推導(dǎo)出后續(xù)結(jié)果,避免函數(shù)調(diào)用開銷,效率更高,本文就來詳細(xì)的介紹一下C++遞推算法的具體使用,感興趣的可以了解一下

遞推算法通過已知的初始條件和遞推關(guān)系,逐步推導(dǎo)出后續(xù)結(jié)果。與遞歸不同,遞推通常使用循環(huán)結(jié)構(gòu)實(shí)現(xiàn),避免了函數(shù)調(diào)用的開銷,效率更高。

本文將用C++語言,通過幾個(gè)經(jīng)典例題,詳細(xì)講解遞推算法的思想和實(shí)現(xiàn)。

一、遞推算法基本思想

遞推算法的核心是遞推關(guān)系式初始條件。

遞推關(guān)系式描述了當(dāng)前狀態(tài)如何由前一個(gè)或多個(gè)狀態(tài)推導(dǎo)而來,而初始條件則是遞推的起點(diǎn)。

在C++中實(shí)現(xiàn)遞推,通常遵循以下步驟:

  1. 定義狀態(tài)數(shù)組:使用數(shù)組存儲(chǔ)中間結(jié)果
  2. 設(shè)置初始條件:根據(jù)問題初始化數(shù)組的前幾項(xiàng)
  3. 建立遞推關(guān)系:通過循環(huán)按照遞推公式計(jì)算后續(xù)項(xiàng)
  4. 輸出結(jié)果:返回或輸出目標(biāo)位置的值

遞推與遞歸的主要區(qū)別在于:遞推是自底向上的迭代過程,而遞歸是自頂向下的函數(shù)調(diào)用過程。遞推通常更高效,適合處理線性結(jié)構(gòu)問題。

二、一維遞推問題

1. 斐波那契數(shù)列

問題描述:斐波那契數(shù)列的第1項(xiàng)為1,第2項(xiàng)為1,從第3項(xiàng)開始,每一項(xiàng)都等于前兩項(xiàng)之和。

遞推關(guān)系f[i] = f[i-1] + f[i-2] 初始條件f[1] = 1, f[2] = 1

C++代碼實(shí)現(xiàn)

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    
    // 定義數(shù)組存儲(chǔ)斐波那契數(shù),假設(shè)n不超過45(保證在int范圍內(nèi))
    int f[46];  // 第45項(xiàng)約為1.13e9,仍在int范圍內(nèi)
    
    // 初始化初始條件
    f[1] = 1;
    f[2] = 1;
    
    // 遞推計(jì)算
    for (int i = 3; i <= n; i++) {
        f[i] = f[i-1] + f[i-2];
    }
    
    cout << f[n] << endl;
    return 0;
}

代碼解析

  • 數(shù)組f存儲(chǔ)已計(jì)算的結(jié)果,避免重復(fù)計(jì)算
  • 循環(huán)從3開始,依次計(jì)算每一項(xiàng)
  • 當(dāng)n≤45時(shí),結(jié)果在int范圍內(nèi)(約21億內(nèi))

2. 爬樓梯問題

問題描述:有n階樓梯,每次可以爬1階或2階,問有多少種不同的爬法。

遞推分析:設(shè)a[i]表示爬到第i階樓梯的方法數(shù)。由于每次只能爬1階或2階,所以到達(dá)第i階只能從第i-1階爬1階,或從第i-2階爬2階。

遞推關(guān)系a[i] = a[i-1] + a[i-2] 初始條件a[1] = 1(爬1階只有1種方法),a[2] = 2(爬2階有2種方法)

C++代碼實(shí)現(xiàn)

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    
    int a[46];  // 假設(shè)n不超過45
    a[1] = 1;
    a[2] = 2;
    
    for (int i = 3; i <= n; i++) {
        a[i] = a[i-1] + a[i-2];
    }
    
    cout << a[n] << endl;
    return 0;
}

代碼解析

  • 這個(gè)問題實(shí)質(zhì)上是斐波那契數(shù)列的變體,只是初始條件不同

三、二維遞推問題

1. 無障礙網(wǎng)格路徑計(jì)數(shù)

問題描述:在一個(gè)m×n的網(wǎng)格中,從左上角(1,1)出發(fā),每次只能向右或向下移動(dòng)一步,要到達(dá)右下角(m,n),問有多少條不同的路徑。

遞推分析:設(shè)b[i][j]表示從起點(diǎn)到達(dá)坐標(biāo)(i,j)的路徑數(shù)。由于只能向右或向下移動(dòng),要到達(dá)(i,j),只能從上方(i-1,j)或左方(i,j-1)過來。

遞推關(guān)系b[i][j] = b[i-1][j] + b[i][j-1] 邊界條件:第一行和第一列的所有位置都只有1條路徑

C++代碼實(shí)現(xiàn)

#include <iostream>
using namespace std;

int main() {
    int m, n;
    cin >> m >> n;
    
    // 使用二維數(shù)組,假設(shè)m和n不超過20
    int b[21] = {0};
    
    // 初始化第一行和第一列
    b[1][1] = 1;
    
    // 遞推計(jì)算
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            if (i == 1 && j == 1) continue; // (1,1)點(diǎn)是初始化條件不用遞推
            b[i][j] = b[i-1][j] + b[i][j-1];
        }
    }
    
    cout << b[m][n] << endl;
    return 0;
}

代碼解析

  • 數(shù)組b[i][j]表示到達(dá)(i,j)的路徑數(shù)
  • 初始化第一行和第一列為1,因?yàn)檠刂吘€只有一條路徑
  • 雙重循環(huán)從(2,2)開始遞推計(jì)算

2. 有障礙網(wǎng)格路徑計(jì)數(shù)

路徑計(jì)數(shù)2(洛谷P1176)

問題描述:一個(gè) N×N 的網(wǎng)格,你一開始在 (1,1),即左上角。每次只能移動(dòng)到下方相鄰的格子或者右方相鄰的格子,問到達(dá) (N,N),即右下角有多少種方法。

但是這個(gè)問題太簡單了,所以現(xiàn)在有 M 個(gè)格子上有障礙,即不能走到這 M 個(gè)格子上。

遞推分析:遞推關(guān)系與無障礙情況類似,但需要額外考慮障礙物:

  1. 如果(i,j)是障礙物,則b[i][j] = true
  2. 否則,a[i][j] =a[i-1][j] + a[i][j-1]

C++代碼實(shí)現(xiàn)

#include <iostream>
using namespace std;

const int MOD = 100003; // 定義模數(shù)常量,避免魔法數(shù)字
int a[1001][1001] = {0}; // 顯式初始化為0
bool b[1001][1001] = {false}; // 顯式初始化為false

int main() {
    int n, m;
    cin >> n >> m;

    // 讀入障礙物
    for (int i = 1; i <= m; i++) {
        int x, y;
        cin >> x >> y;
        b[x][y] = true;
    }

    // 初始化起點(diǎn)
    a[1][1] = 1;

    // 遞推
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            // 跳過起點(diǎn)和障礙物
            if (i == 1 && j == 1) continue;
            if (b[i][j]) continue;
            a[i][j] = (a[i-1][j] + a[i][j-1]) % MOD;
        }
    }

    cout << a[n][n] << endl;
    return 0;
}

四、馬走日(過河卒)問題

問題描述:棋盤上有一個(gè)卒需要從A點(diǎn)(1,1)走到B點(diǎn)(n,m),卒只能向右或向下移動(dòng)。棋盤上有一個(gè)馬,馬走"日"字,馬所在位置及其控制點(diǎn)(馬能走到的8個(gè)位置)卒不能通過。

遞推分析:這是網(wǎng)格路徑計(jì)數(shù)問題的變體,增加了障礙點(diǎn)(馬的控制點(diǎn))。設(shè)b[i][j]表示卒從起點(diǎn)到達(dá)(i,j)的路徑數(shù),stop[i][j]表示(i,j)是否為障礙點(diǎn)。

遞推關(guān)系與有障礙網(wǎng)格類似:

  1. 如果(i,j)是障礙點(diǎn),則b[i][j] = 0
  2. 否則,b[i][j] = b[i-1][j] + b[i][j-1]

C++代碼實(shí)現(xiàn)

#include<bits/stdc++.h>
using namespace std;
// 定義 long long 類型別名,用于存儲(chǔ)可能的大數(shù)結(jié)果
#define ll long long

// 馬的控制點(diǎn)方向數(shù)組:包括馬本身及其8個(gè)走日位置,共9個(gè)方向
// dx和dy分別對(duì)應(yīng)行和列的變化量,其中(0,0)表示馬自身位置
int dx[] = {-2, -2, -1, -1, 0,  1,  1,  2, 2};
int dy[] = {-1,  1, -2,  2, 0, -2,  2, -1, 1};

// 標(biāo)記數(shù)組:s[i][j]=true表示(i,j)是障礙點(diǎn)(馬的控制點(diǎn))
bool s[40];
// 動(dòng)態(tài)規(guī)劃數(shù)組:ans[i][j]表示從起點(diǎn)到達(dá)(i,j)的路徑數(shù)
ll ans[40];

// 變量定義:bx,by為目標(biāo)點(diǎn)坐標(biāo),mx,my為馬的位置坐標(biāo)
int bx, by, mx, my;

int main() {
	// 讀入目標(biāo)點(diǎn)坐標(biāo)和馬的位置坐標(biāo)(原始坐標(biāo)從(0,0)開始)
	cin >> bx >> by >> mx >> my;
	
	// 所有坐標(biāo)加2:偏移操作,防止后續(xù)計(jì)算馬的控制點(diǎn)時(shí)數(shù)組越界
	// 這樣棋盤有效坐標(biāo)從(2,2)開始,對(duì)應(yīng)原坐標(biāo)(0,0)
	bx+=2, by+=2, mx+=2, my+=2;
	
	// 標(biāo)記馬的控制點(diǎn)為障礙(包括馬自身)
	// dx和dy數(shù)組長度為9,索引0~8
	for (int i = 0; i < 9; i++) {
		s[mx+dx[i]][my+dy[i]] = true;
	}
	
	// 遞推初始化:起點(diǎn)(2,2)的路徑數(shù)為1
	ans[2][2] = 1;
	
	// 遞推:遍歷從起點(diǎn)到目標(biāo)點(diǎn)的所有位置
	for (int i = 2; i <= bx; i++) {
		for (int j = 2; j <= by; j++) {
			// 如果當(dāng)前位置是障礙點(diǎn)或是起點(diǎn),則跳過(起點(diǎn)已初始化)
			if (s[i][j] || i==2&&j==2) continue;
			
			// 狀態(tài)轉(zhuǎn)移方程:到達(dá)(i,j)的路徑數(shù)等于從左邊(i,j-1)和從上方(i-1,j)的路徑數(shù)之和
			// 由于卒只能向右或向下移動(dòng),因此只需考慮這兩個(gè)方向
			ans[i][j] = ans[i][j-1] + ans[i-1][j];
		}
	}
	
	// 輸出結(jié)果:到達(dá)目標(biāo)點(diǎn)(bx,by)的路徑數(shù)
	cout << ans[bx][by];
	return 0;
}

五、遞推算法的核心要點(diǎn)

1. 確定遞推狀態(tài)

遞推狀態(tài)是問題的關(guān)鍵,通常用一個(gè)或多個(gè)變量表示問題的某個(gè)狀態(tài)。例如:

  • 爬樓梯問題:a[i]表示到達(dá)第i階的方法數(shù)
  • 網(wǎng)格路徑問題:b[i][j]表示到達(dá)(i,j)的路徑數(shù)

狀態(tài)的定義需要能夠完整描述問題的當(dāng)前情況,并且能夠通過遞推關(guān)系轉(zhuǎn)移到其他狀態(tài)。

2. 建立遞推關(guān)系

遞推關(guān)系描述了狀態(tài)之間的轉(zhuǎn)移方式,通常基于問題的限制條件。

例如:

  • 爬樓梯:一次只能爬1或2階 → a[i] = a[i-1] + a[i-2]
  • 網(wǎng)格路徑:只能向右或向下 → b[i][j] = b[i-1][j] + b[i][j-1]

3. 設(shè)置初始條件

初始條件是遞推的起點(diǎn),必須明確給出。例如:

  • 爬樓梯:a[1] = 1, a[2] = 2
  • 網(wǎng)格路徑:第一行和第一列都為1(無障礙時(shí))

4. 處理邊界情況

邊界情況需要特別小心,例如數(shù)組越界、障礙物檢查等。在編寫代碼時(shí),要確保所有邊界情況都被正確處理。

六、常見錯(cuò)誤與調(diào)試技巧

1. 數(shù)組越界

這是遞推算法中最常見的錯(cuò)誤。要確保數(shù)組下標(biāo)在有效范圍內(nèi),特別是當(dāng)訪問a[i-1]b[i-1][j]等時(shí),要檢查i>1的條件。

2. 初始條件錯(cuò)誤

遞推的初始條件必須正確設(shè)置,否則整個(gè)遞推過程都會(huì)出錯(cuò)。要仔細(xì)分析問題的起點(diǎn)狀態(tài)。

3. 遞推關(guān)系錯(cuò)誤

遞推關(guān)系必須正確反映狀態(tài)之間的轉(zhuǎn)移規(guī)律??梢酝ㄟ^手工計(jì)算小規(guī)模樣例來驗(yàn)證遞推關(guān)系的正確性。

4. 數(shù)據(jù)類型選擇

雖然用戶要求使用int類型,但要確保計(jì)算結(jié)果不會(huì)溢出。對(duì)于可能的大數(shù)據(jù),需要考慮使用更大的數(shù)據(jù)類型。

總結(jié)

遞推算法通過已知條件和遞推關(guān)系,逐步推導(dǎo)出問題的解。在C++中實(shí)現(xiàn)遞推算法,關(guān)鍵是正確定義狀態(tài)、建立遞推關(guān)系、設(shè)置初始條件。通過本文的四個(gè)例題,我們可以看到遞推算法在解決序列問題和網(wǎng)格路徑問題中的應(yīng)用。

對(duì)于初學(xué)者來說,理解遞推思想比掌握高級(jí)數(shù)據(jù)結(jié)構(gòu)更重要。通過大量練習(xí),可以培養(yǎng)將實(shí)際問題轉(zhuǎn)化為遞推模型的能力,這是算法學(xué)習(xí)的重要基礎(chǔ)。遞推算法不僅是動(dòng)態(tài)規(guī)劃的基礎(chǔ),也是許多復(fù)雜算法的核心思想。

在實(shí)際編程中,要注意邊界條件的處理、數(shù)組下標(biāo)的范圍檢查,以及遞推關(guān)系的正確性驗(yàn)證。通過不斷練習(xí)和調(diào)試,可以逐漸掌握遞推算法的精髓,為解決更復(fù)雜的算法問題打下堅(jiān)實(shí)基礎(chǔ)。

到此這篇關(guān)于C++遞推算法的具體使用的文章就介紹到這了,更多相關(guān)C++遞推算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關(guān)文章

  • C++中vector迭代器失效問題詳解

    C++中vector迭代器失效問題詳解

    vector是向量類型,它可以容納許多類型的數(shù)據(jù),如若干個(gè)整數(shù),所以稱其為容器,這篇文章主要給大家介紹了關(guān)于C++中vector迭代器失效問題的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • C++中與輸入相關(guān)的istream類成員函數(shù)簡介

    C++中與輸入相關(guān)的istream類成員函數(shù)簡介

    這篇文章主要介紹了C++中與輸入相關(guān)的istream類成員函數(shù)簡介,包括eof函數(shù)和peek函數(shù)以及putback函數(shù)還有ignore函數(shù),需要的朋友可以參考下
    2015-09-09
  • Linux/Manjaro如何配置Vscode的C/C++編譯環(huán)境

    Linux/Manjaro如何配置Vscode的C/C++編譯環(huán)境

    這篇文章主要介紹了Linux/Manjaro配置Vscode的C/C++編譯環(huán)境,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05
  • C++中的set有序且唯一的集合方式

    C++中的set有序且唯一的集合方式

    這篇文章主要介紹了C++中的set有序且唯一的集合方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-05-05
  • C++11中l(wèi)ambda、std::function和std:bind詳解

    C++11中l(wèi)ambda、std::function和std:bind詳解

    大家都知道C++11中增加了許多的新特性,下面在這篇文中我們就來聊一下lambda表達(dá)式,閉包,std::function以及std::bind。文中介紹的很詳細(xì),相信對(duì)大家具有一定的參考價(jià)值,有需要的朋友們下面來一起看看吧。
    2017-01-01
  • C語言文字藝術(shù)之?dāng)?shù)據(jù)輸入輸出

    C語言文字藝術(shù)之?dāng)?shù)據(jù)輸入輸出

    這篇文章主要介紹了C語言文字藝術(shù)之?dāng)?shù)據(jù)輸入輸出,C語言的語句用來向計(jì)算機(jī)系統(tǒng)發(fā)出操作指令。一條語句編寫完成經(jīng)過編譯后產(chǎn)生若干條機(jī)器指
    2022-07-07
  • C++中vector和數(shù)組之間的轉(zhuǎn)換及其效率問題詳解

    C++中vector和數(shù)組之間的轉(zhuǎn)換及其效率問題詳解

    c++?vector轉(zhuǎn)數(shù)組是一種將vector容器的元素轉(zhuǎn)換為數(shù)組的方法,主要能幫助提高程序的性能和效率,下面這篇文章主要給大家介紹了關(guān)于C++中vector和數(shù)組之間的轉(zhuǎn)換及其效率問題的相關(guān)資料,需要的朋友可以參考下
    2023-03-03
  • C++?STL標(biāo)準(zhǔn)庫之std::list使用介紹及用法詳解

    C++?STL標(biāo)準(zhǔn)庫之std::list使用介紹及用法詳解

    std::list是支持常數(shù)時(shí)間從容器任何位置插入和移除元素的容器,下面這篇文章主要給大家介紹了關(guān)于C++?STL標(biāo)準(zhǔn)庫之std::list使用介紹及用法詳解的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-11-11
  • c語言指針數(shù)組的具體使用

    c語言指針數(shù)組的具體使用

    指針數(shù)組就是存放指針變量的數(shù)組,指針數(shù)組的本質(zhì)是數(shù)組,而非指針,本文主要介紹了c語言指針數(shù)組的具體使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • C++歸并算法實(shí)例

    C++歸并算法實(shí)例

    這篇文章主要介紹了C++歸并算法,實(shí)例分析了C++實(shí)現(xiàn)基于歸并算法合并線性表的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07

最新評(píng)論

大田县| 青阳县| 八宿县| 阿拉善左旗| 延长县| 任丘市| 高碑店市| 华安县| 佛冈县| 什邡市| 丽水市| 根河市| 临猗县| 津南区| 盐山县| 扬中市| 靖州| 江山市| 房产| 永清县| 牡丹江市| 蒲江县| 四会市| 邵阳县| 山东省| 江山市| 平乐县| 临泉县| 绥中县| 滨海县| 汶川县| 禹城市| 寻乌县| 邛崃市| 六枝特区| 虎林市| 崇阳县| 眉山市| 敖汉旗| 揭东县| 蓬溪县|