Problem Description
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).
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
Source
思路:这题没什么思路,加上数学又学的不好.遂先打表找规律.(1-16)
code:
#include <iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#define M 100
using namespace std;
int ans[M];
int ant;
bool vis[10][10][10][10]; // 1 2 4 8
void dfs(int x,int k,int n)
{
if(x==0)
{
int a=0,b=0,c=0,d=0;
for(int j=0; j<k; ++j)
{
if(ans[j]==1)a++;
if(ans[j]==2)b++;
if(ans[j]==4)c++;
if(ans[j]==8)d++;
}
if(!vis[a][b][c][d])
{
vis[a][b][c][d]=true;
for(int j=0; j<k; ++j)
printf("%d ",ans[j]);
printf("\n");
ant++;
}
return ;
}
for(int i=1; i<=n; i*=2)
{
if(x-i>=0)
{
ans[k]=i;
dfs(x-i,k+1,n);
}
}
}
int main()
{
freopen("xx.out","w",stdout);
for(int i=1;i<=16;++i)
{
ant=0;
cout<<"n="<<i<<endl;
memset(vis,0,sizeof(vis));
memset(ans,0,sizeof(ans));
dfs(i,0,i);
cout<<"Result="<<ant<<endl;
}
// cout << "Hello world!" << endl;
return 0;
}
打表结果:
n=1
1
Result=1
n=2
1 1
2
Result=2
n=3
1 1 1
1 2
Result=2
n=4
1 1 1 1
1 1 2
2 2
4
Result=4
n=5
1 1 1 1 1
1 1 1 2
1 2 2
1 4
Result=4
n=6
1 1 1 1 1 1
1 1 1 1 2
1 1 2 2
1 1 4
2 2 2
2 4
Result=6
n=7
1 1 1 1 1 1 1
1 1 1 1 1 2
1 1 1 2 2
1 1 1 4
1 2 2 2
1 2 4
Result=6
n=8
1 1 1 1 1 1 1 1
1 1 1 1 1 1 2
1 1 1 1 2 2
1 1 1 1 4
1 1 2 2 2
1 1 2 4
2 2 2 2
2 2 4
4 4
8
Result=10
n=9
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 2
1 1 1 1 1 2 2
1 1 1 1 1 4
1 1 1 2 2 2
1 1 1 2 4
1 2 2 2 2
1 2 2 4
1 4 4
1 8
Result=10
n=10
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 2
1 1 1 1 1 1 2 2
1 1 1 1 1 1 4
1 1 1 1 2 2 2
1 1 1 1 2 4
1 1 2 2 2 2
1 1 2 2 4
1 1 4 4
1 1 8
2 2 2 2 2
2 2 2 4
2 4 4
2 8
Result=14
n=11
1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 2
1 1 1 1 1 1 1 2 2
1 1 1 1 1 1 1 4
1 1 1 1 1 2 2 2
1 1 1 1 1 2 4
1 1 1 2 2 2 2
1 1 1 2 2 4
1 1 1 4 4
1 1 1 8
1 2 2 2 2 2
1 2 2 2 4
1 2 4 4
1 2 8
Result=14
n=12
1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 2
1 1 1 1 1 1 1 1 2 2
1 1 1 1 1 1 1 1 4
1 1 1 1 1 1 2 2 2
1 1 1 1 1 1 2 4
1 1 1 1 2 2 2 2
1 1 1 1 2 2 4
1 1 1 1 4 4
1 1 1 1 8
1 1 2 2 2 2 2
1 1 2 2 2 4
1 1 2 4 4
1 1 2 8
2 2 2 2 2 2
2 2 2 2 4
2 2 4 4
2 2 8
4 4 4
4 8
Result=20
n=13
1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 2
1 1 1 1 1 1 1 1 1 2 2
1 1 1 1 1 1 1 1 1 4
1 1 1 1 1 1 1 2 2 2
1 1 1 1 1 1 1 2 4
1 1 1 1 1 2 2 2 2
1 1 1 1 1 2 2 4
1 1 1 1 1 4 4
1 1 1 1 1 8
1 1 1 2 2 2 2 2
1 1 1 2 2 2 4
1 1 1 2 4 4
1 1 1 2 8
1 2 2 2 2 2 2
1 2 2 2 2 4
1 2 2 4 4
1 2 2 8
1 4 4 4
1 4 8
Result=20
n=14
1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 2
1 1 1 1 1 1 1 1 1 1 2 2
1 1 1 1 1 1 1 1 1 1 4
1 1 1 1 1 1 1 1 2 2 2
1 1 1 1 1 1 1 1 2 4
1 1 1 1 1 1 2 2 2 2
1 1 1 1 1 1 2 2 4
1 1 1 1 1 1 4 4
1 1 1 1 1 1 8
1 1 1 1 2 2 2 2 2
1 1 1 1 2 2 2 4
1 1 1 1 2 4 4
1 1 1 1 2 8
1 1 2 2 2 2 2 2
1 1 2 2 2 2 4
1 1 2 2 4 4
1 1 2 2 8
1 1 4 4 4
1 1 4 8
2 2 2 2 2 2 2
2 2 2 2 2 4
2 2 2 4 4
2 2 2 8
2 4 4 4
2 4 8
Result=26
n=15
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 2
1 1 1 1 1 1 1 1 1 1 1 2 2
1 1 1 1 1 1 1 1 1 1 1 4
1 1 1 1 1 1 1 1 1 2 2 2
1 1 1 1 1 1 1 1 1 2 4
1 1 1 1 1 1 1 2 2 2 2
1 1 1 1 1 1 1 2 2 4
1 1 1 1 1 1 1 4 4
1 1 1 1 1 1 1 8
1 1 1 1 1 2 2 2 2 2
1 1 1 1 1 2 2 2 4
1 1 1 1 1 2 4 4
1 1 1 1 1 2 8
1 1 1 2 2 2 2 2 2
1 1 1 2 2 2 2 4
1 1 1 2 2 4 4
1 1 1 2 2 8
1 1 1 4 4 4
1 1 1 4 8
1 2 2 2 2 2 2 2
1 2 2 2 2 2 4
1 2 2 2 4 4
1 2 2 2 8
1 2 4 4 4
1 2 4 8
Result=26
n=16
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 2
1 1 1 1 1 1 1 1 1 1 1 1 2 2
1 1 1 1 1 1 1 1 1 1 1 1 4
1 1 1 1 1 1 1 1 1 1 2 2 2
1 1 1 1 1 1 1 1 1 1 2 4
1 1 1 1 1 1 1 1 2 2 2 2
1 1 1 1 1 1 1 1 2 2 4
1 1 1 1 1 1 1 1 4 4
1 1 1 1 1 1 1 1 8
1 1 1 1 1 1 2 2 2 2 2
1 1 1 1 1 1 2 2 2 4
1 1 1 1 1 1 2 4 4
1 1 1 1 1 1 2 8
1 1 1 1 2 2 2 2 2 2
1 1 1 1 2 2 2 2 4
1 1 1 1 2 2 4 4
1 1 1 1 2 2 8
1 1 1 1 4 4 4
1 1 1 1 4 8
1 1 2 2 2 2 2 2 2
1 1 2 2 2 2 2 4
1 1 2 2 2 4 4
1 1 2 2 2 8
1 1 2 4 4 4
1 1 2 4 8
2 2 2 2 2 2 2 2
2 2 2 2 2 2 4
2 2 2 2 4 4
2 2 2 2 8
2 2 4 4 4
2 2 4 8
4 4 4 4
4 4 8
8 8
16
Result=36
可以发现规律了: 当n是奇数的时候,值就等于前面那个偶数的值.n为偶数的时候,它的值等于前面那个奇数的值再加上它本身/2的那个值
AC code:
#include<iostream>
#include<cstdio>
using namespace std;
#define M 1000000
typedef long long ll;
const int mode=1000000000;
int n;
ll num[M]={0,1,2};
void slove()
{
int i,j;
for(i=3;i<=M;++i)
{
if(i&1) num[i]=num[i-1]; //奇数就等于前一位的偶数
else num[i]=(num[i-1]+num[i/2])%mode;//偶数等于前一位+当前数/2
}
}
int main()
{
slove();
while(scanf("%d",&n)!=EOF)
{
//printf("%I64d\n",num[n]);
printf("%I64d\n",num[n]%mode);
//cout<<num[n]<<endl;
}
return 0;
}