Sumsets
Time Limit: 2000MS | Memory Limit: 200000K | |
Total Submissions: 14344 | Accepted: 5709 |
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
題意:給出一個數N,N可以表示成2的冪的和,問有多少種方式。
輸出方式模1000000000。
看到題:首先想到的就是必須打表。
剛開始想著推出公式,推不出來。
然後想用DP
把1~12這12個數的方式都寫出來了,然後就找到了代碼中的規律。
一想,還真是很有道理。
令dp[i]表示數i可以表示的方式。
然後對於一個數N,
若N是奇數,就相當於在N-1的所有方式中,每一種方式加上一個1,(湊不了2),所以=dp[N-1]
若N是偶數,就相當於在N-2中每一種有1的方式加上一個1,然後剩下的沒有1的方式,再加1.
有多少方式是沒有包含1的呢?把沒有一個的方式的每一個數除以2,就得到了dp[n/2],所以有這麼多種。
那為什麼不把這個1和其他的1合在一起湊成2呢?
舉例說明:1 1 1和1 2,你把1 1 1 變成1 1 2 和在1 2 加1變成1 1 2是重複的。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 5 using namespace std; 6 7 const int maxn=1000000+3; 8 9 #define LL long long 10 11 LL dp[maxn]; 12 const LL mod=1000000000; 13 14 int main() 15 { 16 dp[0]=dp[1]=1; 17 for(int i=2;i<maxn;i++) 18 { 19 if(i%2) 20 dp[i]=dp[i-1]; 21 else 22 dp[i]=dp[i-2]+dp[i/2]; 23 while(dp[i]>=mod) 24 dp[i]-=mod; 25 } 26 27 int N; 28 while(~scanf("%d",&N)) 29 { 30 printf("%d ",dp[N]); 31 } 32 33 return 0; 34 }