題目描述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 2intmain()
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....