| ||||||||||
Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | zmmqq Log Out Mail:3(3) Login Log Archive |
Language:
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). 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 |
题目大意:求一个数的划分数?且划分这些数的数字都是2的幂数;如2^0=1, 2^1=2 ,2^2=4;
解题思路:首先,我们看几个数的划分数:
3:
3=1+1+1;
3=1+2;
4:
4=1+1+1+1;
4=1+1+2;
4=2+2;
4=4;
5:
5=1+1+1+1+1;
5=1+1+1+2;
5=1+2+2;
5=1+4;
6:
6=1+1+1+1+1+1;
6=1+1+1+1+2;
6=1+1+2+2;
6=1+1+4;
6=2+2+2;
6=2+4;
可以发现:若n为奇数时,其划分数等于它上一个数的划分数,当n为偶数时,其划分数为其上一个数的划分数,再加上它一半的数的划分数。
如果设dp[i]表示 i 按照题意的划分数。如果i为偶数,那么所有i-1的划分都加上1之后,就是i的划分的一部分,同理,dp[i/2]的划分就是i的另一部分划分。
两者之和就是当i为偶数是的划分数,i为奇数时;i的划分与i-1的划分相同。
所以有动态转移方程:
i为偶数: dp[i] = dp[i-1] + dp[i/2];
i为奇数:dp[i] = dp[i-1] ;
AC代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int dp[10000010];
int main()
{
int n,i,j,k;
dp[1]=1;dp[2]=2;
for(i=3;i<=1000000;i++)
{
if(i%2==0)
{
dp[i]=dp[i-2]+dp[i/2];
dp[i]%=1000000000;
}
else
dp[i]=dp[i-1];
}
scanf("%d",&n);
printf("%d\n",dp[n]);
return 0;
}