數的計算 遞推 遞迴

2021-10-22 16:35:05 字數 1507 閱讀 1237

我們要求找出具有下列性質數的個數(包含輸入的正整數 n)。

先輸入乙個正整數n(n≤1000),然後對此正整數按照如下方法進行處理:

1.不作任何處理;

2.在它的左邊加上乙個正整數,但該正整數不能超過原數的一半;

3.加上數後,繼續按此規則進行處理,直到不能再加正整數為止。

輸入n, 輸出乙個整數(該整數我在**中用re[n]來表示)表示具有該性質的數的個數;

(例如 6 左邊加乙個不大於 6 的一半的數 2 變為 26 , 2 的左邊還可以加不大於 2 的一半的數 1,變為 126)案例

輸入 6

輸出 6

案例中的 6 個數是 6,16,26,126,36,136

這道題可以直接遞迴, 也可以找到它的遞推式來做.

一 遞推解法

利用遞推求解首先就是要找到這道題的遞推式;

當我看懂題意後, 我首先羅列了從 1 開始的多個整數在進行操作後輸出的結果 re[i], 最終發現了這道題的遞推公式就是re[n] = 1 + re[1] + re[2] + re[3] + …+ re[n/2]; 並且初始條件re[1] = 1; 找到了遞推公式, 知道了初始條件我們就可以用這個遞推公式來做這道題了

以下是我利用該遞推式寫的**:

#

include

//遞推法求解;

using

namespace std;

int re[

10005

], n, ans;

intmain()

ans += re[i];}

cout << ans << endl;

return0;

}

二 遞迴解法

這道題還可以利用遞迴來計算, 但如果單純的用遞迴進行回溯,在這道題上就會卡時間(事實上我這樣做就是tle了), 所以又學習了一下, 知道了這裡用到了記憶化搜尋的思想;

就是你要用乙個陣列來記錄你之前已經遍歷過的情況, 再次遇到這種情況就不用再次呼叫函式再算一遍了, 直接把陣列中記錄這種情況的數輸出就行了, 這樣就避免了做過多的無用功, 提高了遞迴的效率;

那麼這道題的遞迴做法就可以用上這種思想了, 下面就是我寫的**了:

#

include

//遞迴法求解;

using

namespace std;

int re[

10005

], n, ans;

intsearch

(int x)

for(

int i =

1; i <= x /

2; i++

)return re[x]

= temp;

}int

main()

P1028 數的計算 (遞迴 遞推)

題目傳送門 思路 設a i 為n i時的方案數。可知當 i 不進行操作有一種方案,然後 i的左邊可以加1,2,i 2,然後又轉化為求解a 1 a 2 a i 2 的方案數。這顯然是乙個遞推過程,由於每個方案都是由字首和得到,所以我們可以用乙個陣列儲存字首和。遞推公式 a i a i 1 a i 2 ...

數的計算(dfs和遞推)

題目描述 我們要求找出具有下列性質數的個數 包含輸入的正整數 n 先輸入乙個正整數 n n 1000 然後對此正整數按照如下方法進行處理 不作任何處理 在它的左邊加上乙個正整數,但該正整數不能超過原數的一半 加上數後,繼續按此規則進行處理,直到不能再加正整數為止。輸入格式 1個正整數 n n 100...

遞推遞迴練習 F 計算組合數

description 計算組合數。c n,m 表示從n個數中選擇m個的組合數。計算公式如下 若 m 0,c n,m 1 否則,若 n 1,c n,m 1 否則,若m n,c n,m 1 否則 c n,m c n 1,m 1 c n 1,m input 第一行是正整數n,表示有n組要求的組合數。接下...