數的計算 遞迴與函式自呼叫演算法

2022-05-13 04:25:12 字數 2090 閱讀 8818

題目描述description

我們要求找出具有下列性質數的個數(包含輸入的自然數n):

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

1.不作任何處理;

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

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

輸入輸出格式input/output

輸入格式:

乙個自然數n(n<=1000)

輸出格式:

乙個整數,表示具有該性質數的個數。

輸入輸出樣例sample input/output

樣例測試點#1

輸入樣例:

6輸出樣例:

6

思路:

方法一:

用遞迴,f(n)=1+f(1)+f(2)+…+f(div/2),當n較大時會超時,時間應該為指數級。

方法二:用記憶化搜尋,實際上是對方法一的改進。設h[i]表示自然數i滿足題意三個條件的數的個數。如果用遞迴求解,會重複來求一些子問題。例如在求h[4]時,需要再求h[1]和h[2]的值。現在我們用h陣列記錄在記憶求解過程中得出的所有子問題的解,當遇到重疊子問題時,直接使用前面記憶的結果。

方法三:

用遞推,用h(n)表示自然數n所能擴充套件的資料個數,則h(1)=1, h(2)=2, h(3)=2, h(4)=4, h(5)=4, h(6)=6, h(7)=6, h(8)=10, h(9)=10.分析以上資料,可得遞推公式:h(i)=1+h(1)+h(2)+…+h(i/2)。此演算法的時間度為o(n*n)。

設h[i]-i按照規則擴充套件出的自然數個數(1≤i≤n)。下表列出了h[i]值及其方案:

方法四:

w是對方法三的改進,我們定義陣列s,s(x)=h(1)+h(2)+…+h(x),h(x)=s(x)-s(x-1),此演算法的時間複雜度可降到o(n)。

方法五:

w還是用遞推,只要作仔細分析,其實我們還可以得到以下的遞推公式: (1)當i為奇數時,h(i)=h(i-1);

w     (2)當i為偶數時,h(i)=h(i-1)+h(i/2).

**①如下(遞迴):

1 #include2

intans;

3void dfs(int m) //

統計m所擴充套件出的資料個數410

intmain()

11

**②如下(非遞迴):

1 #include 2

intmain()

3;

5int

n,p;

6 scanf("

%d",&n);

7 a[1]=1

; 8 a[2]=2

;

9for(p=3;p<=n;p++)

1015

else

16

19}

20 printf("

%d\n

",a[n]);

21return

0;

22 }

放蘋果 遞迴與函式自呼叫演算法

描述 把m個同樣的蘋果放在n個同樣的盤子裡,允許有的盤子空著不放,問共有多少種不同的分法?用k表示 5,1,1和1,5,1 是同一種分法。輸入第一行是測試資料的數目t 0 t 20 以下每行均包含二個整數m和n,以空格分開。1 m,n 10。輸出對輸入的每組資料m和n,用一行輸出相應的k。樣例輸入 ...

等差數列問題 遞迴與函式自呼叫演算法

題目描述 description 給定n n 1 用遞迴的方法計算1 2 3 4 n 1 n 輸入輸出格式input output 輸入格式 一行,乙個數n 輸出格式 一行,結果 輸入輸出樣例sample input output 樣例測試點 1 輸入樣例 3輸出樣例 6 思路 執行程式,當t 5時...

js函式實現遞迴自呼叫的方法

1.通過函式自身名字遞迴呼叫 function sum num else console.log sum 5 15 這種通過函式名字呼叫自身的方式存在乙個問題 函式的名字是乙個指向函式物件的指標,如果我們把函式的名字與函式物件本身的指向關係斷開,這種方式執行時將出現錯誤。2.通過arguments....