poj 2229 Sumsets (DP?)
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
..............................................................................................................................................
其实个人不觉得是DP。。就是递推吧,看了别人的思路才知道的。
a[ i ] 保存结果,初值 a[ 1 ]=1,a[ 2 ]=2, 然后分两种情况:
i 为奇数时,a[ i ]=a[ i-1 ]
i 为偶数时,a[ i ]=a[ i-1 ]+a[ i/2 ]
想一下,在某个 i 的结果中,能把 1 加起来配成2的倍数的在这个结果里肯定就配完了,所以i+1 的结果中一部分是在i 的结果里加1,一部分就是把 i 的结果中没配成2的倍数的配成倍数,这就是比 i 的结果多的那部分,比如 1 2 2 --+1--> 2 2 2,1 1 1 2 --+1--> 4 2,可知这部分的结果都是2的倍数,想到 i/2 的结果*2都是2的倍数并且它们不能继续合并了,所以这部分就=i/2的结果。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 int a[1000001]; 8 int main() 9 { 10 a[1]=1;a[2]=2; 11 for(int i=3;i<=1000000;i++){ 12 if(i%2==0){ 13 a[i]=(a[i-1]+a[i/2])%1000000000; 14 } 15 else a[i]=a[i-1]; 16 } 17 int n; 18 cin>>n; 19 printf("%d\n",a[n]); 20 return 0; 21 }

浙公网安备 33010602011771号