Poj 2229 Sumsets
http://poj.org/problem?id=2229
题意:给一个正整数N,用2的i次幂的加和表示,有多少方法。
题解:原始DP的思想,Nlog(N)的复杂度,不预处理的话会TLE……
还有一种思想是如果这个数是奇数,那组成它的第一个数一定是1,则dp[i]=dp[i-1];如果这个数是个偶数,若第一个数为1,则dp[i]=dp[i-1],否则都为2的(大于0的)倍数,推出dp[n]=dp[n-1]+dp[n/2]。O(N)的复杂度。
1 // 2 // main.cpp 3 // POJ 2229(DP) 4 // 5 // Created by zhang on 14-4-1. 6 // Copyright (c) 2014年 apple. All rights reserved. 7 // 8 9 #include <iostream> 10 #include <cstdio> 11 12 using namespace std; 13 14 const int maxn=1000010; 15 const int MOD=1000000000; 16 int dp[maxn]; 17 18 int main() 19 { 20 int N; 21 //while (scanf("%d",&N)) { 22 dp[0]=1; 23 for (int i=1; i<=maxn; i*=2) { 24 for (int j=i; j<=maxn; j++) { 25 dp[j]=(dp[j]+dp[j-i])%MOD; 26 } 27 } 28 while (scanf("%d",&N)!=EOF) { 29 printf("%d\n",dp[N]); 30 } 31 32 //} 33 return 0; 34 }
1 // 2 // main.cpp 3 // POJ 2229 4 // 5 // Created by zhang on 14-4-1. 6 // Copyright (c) 2014年 apple. All rights reserved. 7 // 8 9 #include <iostream> 10 #include <cstdio> 11 12 using namespace std; 13 14 const int maxn=1000005; 15 const long long MOD=1000000000; 16 int dp[maxn]; 17 18 int main() 19 { 20 int N; 21 22 while ((scanf("%d",&N))!=EOF) { 23 dp[1]=1; 24 dp[2]=2; 25 for (int i=3; i<=N; i++) { 26 if ((i%2)==1) { 27 dp[i]=dp[i-1]; 28 } 29 else dp[i]=(dp[i-1]+dp[i/2])%MOD; 30 } 31 printf("%d\n",dp[N]); 32 33 } 34 return 0; 35 }