题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2709
感觉很经典的一道递推题
自己想了有半天的时间了。。。。比较弱。。。。
思路:
设f[n]表示和为n的组合数;
那么 当n为奇数时,很简单,相当于在f[n-1]的每一个组合方案中的后面加1 所以当n为奇数时,f[n]=f[n-1];
我们重点讨论n为偶数的情况:
n为偶数时,分为每个方案中有1和无1进行讨论:
有1的话,相当与在f[n-1]后面加1 所以有1时为f[n]=f[n-1];
不含1的话,则就是对f[n/2]的方案数中的每一个数乘以2, 所以就是f[n/2]的方案数,
所以 n为偶数时,f[n]=f[n-1]+f[n/2];
推的过程中最难想到的就是n为偶数且不含1的情况了啊 ,感觉很妙。
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstdio> 4 #include<cstring> 5 using namespace std; 6 #define MAX 1000100 7 #define MOD 1000000000 8 int f[MAX]; 9 int main() 10 { 11 memset(f,sizeof(0),sizeof(f)); 12 f[1]=1; 13 f[2]=2; 14 f[3]=2; 15 for(int i=4;i<=1000000;i++) 16 if(i%2) f[i]=f[i-1]%MOD; 17 else { 18 f[i]=f[i-1]+f[i/2]; 19 f[i]=f[i]%MOD; 20 21 }; 22 int n; 23 while(scanf("%d",&n)!=EOF) 24 { 25 cout<<f[n]<<endl; 26 } 27 return 0; 28 }