题目:
Farmer John commanded his cows to search for different sets of numbers that sum to a given number. The cows use only numbers that are an integer power of 2. Here are the possible sets of numbers that sum to 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
Help FJ count all possible representations for a given integer N (1 <= N <= 1,000,000).
Input
A single line with a single integer, N.
Output
The number of ways to represent N as the indicated sum. Due to the potential huge size of this number, print only last 9 digits (in base 10 representation).
Sample Input
7
Sample Output
6
题意:
把一个数字拆开,拆成一些 2^n 的数字的和,问你有多少种不同的拆解的方法;
思路:
数字的范围很大,所以不能直接搜索,那么这道题就会是一个有规律的题;
我们可以来看看,一个数字进行拆分,那么我们首先可以把所有的数字先拆解成数字 1,然后再进行合并,每两个1可以合并成为一个数字2,那么每两个数字2可以合并成一个数字4,依次合并下去;
那么这样我们就可以看出来了n(偶数)和n+1(奇数)的结果是没有变化的;
原因:因为对于一个偶数来说,它自己本身分解的1的个数可以正好合并成2,但是你加入了一个数字1也是孤单的一个1,并不会加入合并的队列中,那么这个1就不会对结果造成任何的影响,所以结果是不会发生变化的;
但是当n(奇数)和n+1(偶数)时,这个结果就会发生变化了;
原因:因为是一个奇数,那么在本身的合并中就会有一个数字1在单独着,那么你加入了一个1,这样下面的合并就会多出来一个2,后面的合并也会受到影响;
n==7 n==8 n==4
可以明显看出来这两个数值的差距:最开始的1不要先合并,就可以看出来和前面的一个的差距;
后面多出来的数字就可以换算成一个4个1的组合结果;
因为数字最大输出是9位数,所以记得结果要对10^10取模;
代码如下:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=1000010;
const int MOD=1000000000;
long long dp[N];
long long n;
void init()
{
memset(dp,0,sizeof dp);
dp[0]=0;
dp[1]=1;
dp[2]=2;
for(int i=3;i<N;i++)
{
if(i%2==1)//奇数;
dp[i]=dp[i-1]%MOD;
else//偶数;
dp[i]=(dp[i-2]+dp[i/2])%MOD;
}
return ;
}
int main()
{
init();
while(~scanf("%lld",&n))
{
printf("%lld\n",dp[n]);
}
return 0;
}