-
一个整数总可以拆分为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
-
题目描述:
-
输入:
-
输出:
-
样例输入:
-
样例输出:
这道题技巧性非常强,就是列出前几个的值,然后找规律。
当N为奇数时,只是在前一个偶数的基础上加了个1,所以对于拆分数并没有影响,所以f(N) = f(N-1)
当N为偶数时,有两种情况,一种是包含1的,另一种是不包含1的。前一种和f(N-1)是类似的,后一种情况,把每个数都除以2,是不是就是f(N/2),举个例子,8 的拆分数除了包含1的,也就是在7的拆分数基础上,在每个式子右边加个1.还包括另一种情况:
不包含1的,这种情况类似于4的拆分数。
因为
4 = 4
4 = 2 + 2
4 = 2 + 1 + 1
4 = 1 + 1 + 1 + 1
那么对应着8的第二种情况的拆分数就是:
8 = 8
8 = 4 + 4
8 = 4 + 2 + 2
8 = 2 + 2 + 2 + 2,这几种情况就是在4的拆分情况中将每个数乘以2. 但是它们的拆分数是一样的。
还有一点,题目中说的N最大可以到1000000,但是在我的编译器Dev C++里面,只要一执行int f[1000000],立马奔溃,泪奔。
#include <iostream>
using namespace std;
#define mod 1000000000
int main(){
int N;
int f[1000002];
f[0] = f[1] = 1;
for(int i=1;i<=500000;i++){
f[2*i] = (f[2*i-1] + f[i])%mod;
f[2*i+1] = f[2*i];
}
while(cin>>N){
cout<<f[N]<<endl;
}
return 0;
}