递推 & 递归
递推就是从问题的初始状态出发,通过状态之间的逻辑关系,逐步的层层推进,实现状态的转移,达到目标状态的解题方法。而递归就是从问题的目标状态出发,不断的把问题规模缩小,最终达到问题边界条件的解题方法。
例1:蟠桃记
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> using namespace std; int AmountPeach(int n){ if(n==1) return 1; else return 2*(AmountPeach(n-1)+1); } int main() { int day; while(cin>>day){ cout << AmountPeach(day) <<endl; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> using namespace std; int f[105]; int main() { int a,b, i; long n; while(cin>>a>>b>>n && a+b+n){ f[0] = (a+b)% 7; f[1] = (a*f[0]+b)%7; for(i=2;i<100; i++){ f[i]=(a*f[i-1]+b*f[i-2])%7; if(f[i]==f[1] && f[i-1] == f[0]) break; } if(n<2){ cout << 1 <<endl; } else{ n = (n-3) % (i-1); cout << f[n] <<endl; } } return 0; }
例3:不容易系列之一
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <stdio.h> using namespace std; long long f[25]; int main() { int num; f[1]=0; f[2] =1; for(int i=3; i<=20; i++){ f[i] = (i-1)*(f[i-1]+f[i-2]); } while(cin>>num){ cout<<f[num]<<endl; } }
f[n]表示n个人的合法队列, 讨论最后一个人。
1、最后一个人是男。则对n-1个人的队列没有任何限制,故共f[n-1];
2、最后一个人是女。
(1)前n-1个人的队列合法。共f[n-2];
(2)前n-1个人的队列不合法。只有一种情况:前n-4个人的队列合法,第n-3个人为男,第n-2个人为女。共f[n-4];
故,f[n]=f[n-1]+f[n-2]+f[n-4].
考虑到数据比较大。故使用高精度。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <string> #include <cstring> using namespace std; int numQueue[1024][305]; int main() { int num, flag, k = 0; memset(numQueue, 0, sizeof(numQueue)); numQueue[1][0] = 1;numQueue[2][0] = 2;numQueue[3][0]=4;numQueue[4][0] =7; for(int i=5; i<=1000; i++){ for(int j=0; j<=k; j++){ numQueue[i][j] += numQueue[i-1][j] + numQueue[i-2][j] + numQueue[i-4][j]; numQueue[i][j+1] += numQueue[i][j]/10; numQueue[i][j] %= 10; } if(numQueue[i][k+1]!=0) k++; } while(cin >> num){ flag = 1; for(int j=300; j>=0; j--){ if( flag && numQueue[num][j] != 0 ) flag = 0; if(!flag) cout << numQueue[num][j]; } cout << endl; } return 0; }
例5:神、上帝以及老天爷
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <stdio.h> using namespace std; long long f[25]; int main() { double s; //不能long类型,why? int num, t; f[1]=0; f[2] =1; for(int i=3; i<=20; i++){ f[i] = (i-1)*(f[i-1]+f[i-2]); } cin >> t; while(t--){ cin >> num; s=1; for(int i=2; i<=num; i++) s*= i; printf("%.2lf%%\n",(f[num]*1.0)/s*100); } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> using namespace std; int f[105]; int main() { int k; long n; f[0] = 7% 3; f[1] = 11 %3; for(int i=2;i<100; i++){ f[i]=(f[i-1]+f[i-2])%3; if(f[i]==f[1] && f[i-1] == f[0]){ k =i-1; break; } } while(cin>>n){ if(f[n%k] ==0 ) cout << "yes"<<endl; else cout << "no" <<endl; } return 0; }