我們要求找出具有下列性質數的個數(包含輸入的自然數n
nn):
先輸入乙個自然數n
nn(n
≤1000
n\leq1000
n≤1000
),然後對此自然數按照如下方法進行處理:
不作任何處理;
在它的左邊加上乙個自然數,但該自然數不能超過原數的一半;
加上數後,繼續按此規則進行處理,直到不能再加自然數為止.
自然數n
nn,且n
≤1000
n\leq1000
n≤1000
1個整數,表示具有該性質數的個數
輸入
輸出 解釋:滿足的數分別為6,16,26,126,36,136顯然,最簡單直接的做法就是遞迴(將乙個大問題規約成更小規模的子問題,通過子問題的求解完成原問題)
假設:當輸入為4時,滿足的其性質的數有——4本身,加上其規模1/2
^1/_2
1/2
的子問題解的個數,即 4,24, 124
根據我們的分析,演算法的也就不難寫出來了,遞迴**如下
int
fun(
int n)
return cnt+1;
}
遞迴的方法雖然簡單直觀,但是提交沒過——超時了,遞迴深度太深導致爆棧了,這時候我們就需要思考能不能改進?能不能進一步優化?
還記得最初在學習遞迴的時候,乙個經典的案例就是斐波那契數列:f(n
)=f(
n−1)
+f(n
−2),
n≥
2f(n) = f(n-1) + f(n-2), n\geq2
f(n)=f
(n−1
)+f(
n−2)
,n≥2(2
)f(2)
f(2)
的值就被重複計算了三次,那麼我們能不能讓它只計算一次呢?
對於斐波那契數列的一種優化方法就是利用陣列暫存中間值,這樣就避免了重複計算
那麼什麼又是動態規劃?
遵循動態規劃演算法是將問題遞迴地分解成更簡單的重疊子問題,通過子問題的解決來解決原問題在斐波那契數列的例子中,多次計算的f(2動態規劃目前已廣泛應用於經濟學、計算機視覺、語音識別、人工智慧、計算機圖形學和生物資訊學
)f(2)
f(2)
的值,這樣就是乙個重疊的子問題,我們應避免重複計算帶來的時間開銷,於是引入了陣列——儲存每一次計算的值(這樣乙個過程稱為記憶, 對於提高遞迴演算法效率是很重要的技術)
我們有了思路,下面的關注點就在於尋找該問題的乙個遞推關係式
我們先列出來一部分:(其中f(n
)f(n)
f(n)
表示自然數n
nn所具有上述三種性質的個數)
f (1
)=
1f(1) = 1
f(1)=1
f (2
)=
2f(2) = 2
f(2)=2
f (3
)=
2f(3) = 2
f(3)=2
f (4
)=
4f(4) = 4
f(4)=4
f (5
)=
4f(5) = 4
f(5)=4
f (6
)=
6f(6) = 6
f(6)=6
f (7
)=
6f(7) = 6
f(7)=6
f (8
)=
10f(8) = 10
f(8)=10f(
9)=10
f(9) = 10
f(9)=1
0…我們可以看出:
綜上,我們可以得出遞推式:
f (1
)=
1f(1) = 1
f(1)=1
n
>
1n>1
n>1時
long
fun(
int n)
return a[n]
;}
學習演算法的道路漫長且艱鉅,唯有不斷打磨自己不斷思考,挖掘其背後的本質,才能取得進步 洛谷P1028 數的計算
我們要求找出具有下列性質數的個數 包含輸入的自然數n 先輸入乙個自然數n n 1000 然後對此自然數按照如下方法進行處理 1.不作任何處理 2.在它的左邊加上乙個自然數,但該自然數不能超過原數的一半 3.加上數後,繼續按此規則進行處理,直到不能再加自然數為止.輸入格式 乙個自然數n n 1000 ...
洛谷 P1028 數的計算
我們要求找出具有下列性質數的個數 包含輸入的自然數n 先輸入乙個自然數n n 1000 然後對此自然數按照如下方法進行處理 不作任何處理 在它的左邊加上乙個自然數,但該自然數不能超過原數的一半 加上數後,繼續按此規則進行處理,直到不能再加自然數為止.輸入格式 乙個自然數n n 1000 輸出格式 乙...
洛谷P1028 數的計算
我們要求找出具有下列性質數的個數 包含輸入的自然數 n 先輸入乙個自然數n n 1000 然後對此自然數按照如下方法進行處理 不作任何處理 在它的左邊加上乙個自然數,但該自然數不能超過原數的一半 加上數後,繼續按此規則進行處理,直到不能再加自然數為止.輸入格式 1 個自然數n n 1000 輸出格式...