牛客網 整數拆分

2022-07-17 21:30:19 字數 2351 閱讀 2555

題目描述:

乙個整數總可以拆分為2的冪的和,例如: 7=1+2+4 7=1+2+2+2 7=1+1+1+4 7=1+1+1+2+2 7=1+1+1+1+1+2 7=1+1+1+1+1+1+1 總共有六種不同的拆分方式。 再比如:4可以拆分成:4 = 4,4 = 1 + 1 + 1 + 1,4 = 2 + 2,4=1+1+2。 用f(n)表示n的不同拆分的種數,例如f(7)=6. 要求編寫程式,讀入n(不超過1000000),輸出f(n)%1000000000。

輸入描述:

每組輸入包括乙個整數:n(1<=n<=1000000)。

輸出描述:

對於每組資料,輸出f(n)%1000000000。

輸入

7輸出

6解題思路(摘):

記f(n)為n的劃分數,我們有遞推公式:

f(2m + 1) =f(2m)

f(2m) = f(2m - 1) + f(m)

初始條件:f(1) = 1。

證明:

證明的要點是考慮劃分中是否有1。

記:

a(n) = n的所有劃分組成的集合,

b(n) = n的所有含有1的劃分組成的集合,

c(n) = n的所有不含1的劃分組成的集合,

則有: a(n) = b(n)∪c(n)。

又記:f(n) = a(n)中元素的個數,

g(n) = b(n)中元素的個數,

h(n) = c(n)中元素的個數,

易知: f(n) = g(n) + h(n)。

我們先來證明: f(2m + 1) = f(2m),

首先,2m + 1 的每個劃分中至少有乙個1,去掉這個1,就得到 2m 的乙個劃分,故 f(2m + 1)≤f(2m)。

其次,2m 的每個劃分加上個1,就構成了 2m + 1 的乙個劃分,故 f(2m)≤f(2m + 1)。

綜上,f(2m + 1) = f(2m)。

接著我們要證明: f(2m) = f(2m - 1) + f(m),

把 b(2m) 中的劃分中的1去掉乙個,就得到 a(2m - 1) 中的乙個劃分,故 g(2m)≤f(2m - 1)。

把 a(2m - 1) 中的劃分加上乙個1,就得到 b(2m) 中的乙個劃分,故 f(2m - 1)≤g(2m)。

綜上,g(2m) = f(2m - 1)。

把 c(2m) 中的劃分的元素都除以2,就得到 a(m) 中的乙個劃分,故 h(2m)≤f(m)。

把 a(m) 中的劃分的元素都乘2,就得到 c(2m) 中的乙個劃分,故 f(m)≤h(2m)。

綜上,h(2m) = f(m)。

所以: f(2m) = g(2m) + h(2m) = f(2m - 1) + f(m)。

**:

#include #include 

#include

#include

using

namespace

std;

long ans[1000001

];//

n表示ans計算到哪個數字

intn;

/*f(2m + 1) = f(2m),

f(2m) = f(2m - 1) + f(m)

*/void caculate(int n, int

n)

else

ans[i] = ans[i] % 1000000000

; }

}int

main()

caculate(n,n);

cout

<< ans[n]

}return0;

}

牛客網刷題 整數拆分

題目描述 乙個整數總可以拆分為2的冪的和,例如 7 1 2 4 7 1 2 2 2 7 1 1 1 4 7 1 1 1 2 2 7 1 1 1 1 1 2 7 1 1 1 1 1 1 1 總共有六種不同的拆分方式。再比如 4可以拆分成 4 4,4 1 1 1 1,4 2 2,4 1 1 2。用f n...

牛客網 進製轉換(大整數)

將乙個長度最多為30位數字的十進位製非負整數轉換為二進位制數輸出。輸入描述 多組資料,每行為乙個長度不超過30位的十進位製非負整數。注意是10進製數字的個數可能有30個,而非30bits的整數 輸出描述 每行輸出對應的二進位制數。只是十進位制轉二進位制的話,並沒有難度。就是依次去 2,直到被除數為0...

牛客網C語言整數奇偶排序

輸入10個整數,彼此以空格分隔。重新排序以後輸出 也按空格分隔 要求 1.先輸出其中的奇數,並按從大到小排列 2.然後輸出其中的偶數,並按從小到大排列。任意排序的10個整數 0 100 彼此以空格分隔。可能有多組測試資料,對於每組資料,按照要求排序後輸出,由空格分隔。1.測試資料可能有很多組,請使用...