题意:大致为求2的幂次集组成数n的组成方法的个数
1. 使用完全背包dp直接求解,这样的复杂度为o(nlogn)
#include<iostream> #include<cstdio> using namespace std; const int MAX_N = 1000000; const int T = 1000000000; int n; int dp[MAX_N+1]; int a[20]; int main () { scanf("%d", &n); int m = 0; a[0] = 1; dp[0] = 1; while(a[m] <= n) { m++; a[m] = 2 * a[m-1]; } for(int i = 0; i < m; i++) { for(int j = 1; j <= n; j++) { if(j >= a[i]) dp[j] = (dp[j] + dp[j - a[i]]) % T; } } printf("%d ", dp[n]); return 0; }
2.利用规律(我是找不到。。。)
对于奇数n来说dp[n] = dp[n-1],对于偶数的n来说,它的组成可分为两类,有1和没1的,有1的数量为dp[n-1],没1的为dp[n/2],则dp[n] = dp[i-1]+dp[i/2];
代码:
#include<iostream> #include<cstdio> using namespace std; const int MAX_N = 1000000; const int T = 1000000000; int n; int dp[MAX_N+1]; int main () { scanf("%d", &n); int m = 0; dp[0] = 1; for(int i = 1; i <= n; i++) { if(i%2) dp[i] = dp[i-1]; else dp[i] = (dp[i-1] + dp[i/2])%T; } printf("%d ", dp[n]); return 0; }