原题
题目分析
计数dp,dp[i]定义为i有多少种分解方案,对一个数i,首先如果它是奇数,则它的方案总数与i-1的方案总数相同,因为只需要在i-1的每个分解方案+1即可.如果它是偶数,则i/2的每个分解方案的每个数*2即可得到i,这样得到的i的分解方案是不存在1的(因为*2所以至少为2),因此还要考虑有1的时候i的分解方案有多少种,可以这样想,先忽略两个1,考虑剩下的数任意组合的方法数,也就是i-2的方案数,最后再加上两个1即可归为有1的时候i的分解方案数.if(dp[i]&1) dp[i]=dp[i-1].else dp[i]=dp[i-2]+dp[i/2].初始化dp[0]=dp[1]=1.递推就可以了.
代码
1 #include <iostream> 2 #include <algorithm> 3 #include <utility> 4 #include <cstdio> 5 #include <cmath> 6 #include <cstring> 7 #include <string> 8 #include <vector> 9 #include <stack> 10 #include <queue> 11 #include <map> 12 #include <set> 13 14 using namespace std; 15 typedef long long LL; 16 const int INF_INT=0x3f3f3f3f; 17 const LL INF_LL=0x3f3f3f3f3f3f3f3f; 18 19 const int mod=1e9; 20 LL dp[2000000]; 21 22 int main() 23 { 24 // freopen("black.in","r",stdin); 25 // freopen("black.out","w",stdout); 26 int n; 27 cin>>n; 28 dp[0]=1,dp[1]=1; 29 for(int i=2;i<=n;i++) 30 { 31 if(i&1) dp[i]=dp[i-1]; 32 else dp[i]=(dp[i-2]+dp[i/2])%mod; 33 } 34 cout<<dp[n]<<endl; 35 return 0; 36 }