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).
A single line with a single integer, N.
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).
7
6
题意:
问你一个数字有多少种由2的整数幂组成。
思路:
当时没想那么多,写了几组数据之后,发现了规律。
例如:
1 1种
2 2种
3 2种
4 4种
5 4种
6 6种
7 6种
8 10种。。。
不难发现规律,当数字大于2时,当为奇数则a[n]=a[n-1];
当为偶数是 a[n]=a[n-1]+a[n/2];
还有一种方法就是用dp。
状态:
d[i][j]表示前i个二的幂数凑成数j的方法数
空间可以降维到d[j]
状态转移方程:
d[j]=d[j]+d[j-c[i]]
c[i]=2^i
边界:
d[0]=1
dp代码:
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
int dp[1000005],c[25];
int n,i,j;
int main()
{
scanf("%d",&n);
c[0]=dp[0]=1;
for(i=1;i<=20;i++)
c[i]=c[i-1]<<1;
for(i=0;i<=20&&c[i]<=n;i++)
for(j=c[i];j<=n;j++)
dp[j]=(dp[j-c[i]]+dp[j])%1000000000;
cout<<dp[n]<<endl;
}
递推代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#include <iomanip>
#define maxn 1000005
#define mod 1000000000
#define INF 0x3f3f3f3f
#define exp 1e-6
#define pi acos(-1.0)
using namespace std;
int a[maxn];
int main()
{
ios::sync_with_stdio(false);
int i,n;
a[1]=1;
a[2]=2;
for(i=3;i<maxn;i++)
{
if(i%2==0) a[i]=(a[i-1]+a[i/2])%mod;
else a[i] = a[i-1];
}
while(cin>>n)
{
cout<<a[n]<<endl;
}
return 0;
}