九度OJ 1084 整数拆分

来源:互联网 发布:java私有对象 编辑:程序博客网 时间:2024/04/29 19:49
题目描述:

一个整数总可以拆分为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 1000000000int 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;}


0 0
原创粉丝点击