描述
题目描述
一个整数总可以拆分为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。
示例1
输入
7
输出
6
分析
显然f[1]=1 f[2]=2
当n是奇数时,只能拆成1+(n-1),而1不能再拆分,所以实际上f[n] = f[n-1]
当n为偶数时,拆分的结果中有两种情况,一种是包含1的,比如1+2+1,另一种是不包含1的,比如2+2
含有1的情况中,由于n是偶数,则必然至少含有两个1,这两个1不会再拆分,所以种类数由剩下的n-2的拆分决定,所以是f[n-2];
当不含有1时,那么拆分出的所有数都是2的倍数,也就是n = 2*(n/2),能够拆分出的种类由这n/2决定,所以是f[n/2]
所以当n为偶数时, f[n] = f[n-2] + f[n/2]
另外由于数据过大,需要边计算边取模
代码
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
#include<cctype>
using namespace std;
const int mod = 1000000000;
const int N = 1000000;
long long f[N + 2];
int main()
{
int n;
f[1] = 1; f[2] = 2;
for (int i = 3; i <= N; i++)
{
if (i % 2 != 0)f[i] = f[i - 1];
else f[i] = (f[i / 2]%mod + f[i - 2]%mod)%mod;
}
while (cin>>n)
{
printf("%lld\n", f[n] % mod);
}
}