POJ2229 Sumsets 基礎DP

                        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). 

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\n",dp[N]);
31     }
32 
33     return 0;
34 }
View Code

 

 

 

 

 
 
 
 
 
 
 
posted on 2015-06-26 23:17  _fukua  阅读(159)  评论(0编辑  收藏  举报