最近遇到這樣的一道題,用到了遞迴,採用兩種辦法實現,第一種超時,第二種滿足要求。演算法小白也算是遞迴有了乙個初探。題目如下:
乙個正整數可以表示為多個正整數相加的表示式,表示式中的各個正整數要求都是2的冪。例如給定正整數7,它有下列六個符合要求的表示式:
1)1+1+1+1+1+1+1
2)1+1+1+1+1+2
3)1+1+1+2+2
4)1+1+1+4
5)1+2+2+2
6)1+2+4
因此,正整數7符合條件的表示式個數是6. 編寫乙個程式,對於給定的正整數n(1 <= n <= 1,000),輸出符合條件的表示式個數。要求:時間複雜度不高於o(n)。
起初沒有思路,參考 用c寫了兩種方法。
一、遞推公式
我們可以先分析如下幾個例子:
1的分解方法 有1種 1
2的分解方法 有2種
1 +1 2
3的分解方法 有2種
1+1+1
1+24的分解方法 有4種
1+1+1+1
1+1+2
2+2 4
5的分解方法有 4種
1+1+1+1+1
1+1+1+2
1+2+2
1+46的分解方法有 6種
1+1+1+1+1+1
1+1+1+1+2
1+1+2+2
1+1+4
2+2+2
2+47的分解方法有6種
1+1+1+1+1+1+1
1+1+1+1+1+2
1+1+1+2+2
1+1+1+4
1+2+2+2
1+2+4
列舉的上述幾個我們不難發現這樣幾個規律
對於任意乙個奇數n(除1之外)都和他前面乙個的偶數n-1的分解方案相等
對於任意乙個偶數(n)都等於他前面的乙個奇數(n-1)的分解方案數加上(n/2)方案的數
那麼由此可以得出我們的遞迴公式
n位1時:f(n)
n為奇數時f(n)=f(n-1);
n為偶數是f(n)=f(n-1)+f(n/2);
二、方法一
根據遞迴公式我們很容易寫出遞迴函式
#include
#include
int f(int n)
int main()
return 0;}
但是利用這種方法會超時,這是因為,你計算f(100)的時候層層遞迴,f(10)會被算很多次。這樣數越大,算的越多,很浪費。因此有了下一種方法。
二、方法二
我們利用乙個陣列,從1到n的分解數都存在乙個陣列中,用到的時候直接呼叫,這樣就不會超時啦啦啦啦
#include
#include
int main()
else
}printf("%d\n", m[a]);
}return 0;
}
整數分解為2的冪 數學
任何正整數都能分解成2的冪,給定整數n,求n的此類劃分方法的數量!由於方案數量較大,輸出mod 1000000007的結果。比如n 7時,共有6種劃分方法。7 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 2 2 1 2 2 2 1 1 1 4 1 2 4 input輸入乙個數n ...
1383 整數分解為2的冪
1383 整數分解為2的冪 基準時間限制 1 秒 空間限制 131072 kb 任何正整數都能分解成2的冪,給定整數n,求n的此類劃分方法的數量!由於方案數量較大,輸出mod 1000000007的結果。比如n 7時,共有6種劃分方法。7 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 ...
51Nod 1383 整數分解為2的冪
任何正整數都能分解成2的冪,給定整數n,求n的此類劃分方法的數量!由於方案數量較大,輸出mod 1000000007的結果。比如n 7時,共有6種劃分方法。7 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 2 2 1 2 2 2 1 1 1 4 1 2 4 看到這題就是乙個遞推題,...