常用递推式
后面问题的解可以由前面问题的解递推而来,每一项都与前面若干项有一定关联。它是一种用若干步可以重复的简单运算来描述复杂问题的方法。
爬楼梯和兔子问题和斐波那契:f(n)=f(n−1)+f(n−2);f(1)=1,f(2)=1f(n)=f(n-1)+f(n-2) ; f(1)=1,f(2)=1 f(n)=f(n−1)+f(n−2);f(1)=1,f(2)=1
直线分割平面:f(n)=f(n−1)+nf(n)=f(n-1)+n f(n)=f(n−1)+n
n封信,n个信封,所有信装错了信封可能情况总数(错排公式):
f(n)=(n−1)(f(n−1)+f(n−2));f(1)=0,f(2)=1f(n)=(n-1)(f(n-1)+f(n-2)) ;f(1)=0,f(2)=1 f(n)=(n−1)(f(n−1)+f(n−2));f(1)=0,f(2)=1
杨辉三角:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
f[i][j]=f[i−1][j−1]+f[i−1][j];(j不为1的时候)f[i][j]=f[i-1][j-1]+f[i-1][j];(j不为1的时候) f[i][j]=f[i−1][j−1]+f[i−1][j];(j不为1的时候)
f[i][j]=1(j为1的时候)f[i][j]=1(j为1的时候) f[i][j]=1(j为1的时候)
实现递推:
一维递推以斐波那契为例:
#include <iostream>
using namespace std;
const int N = 1e3;
typedef long long ll;
ll f[N];int main() {int n;cin>>n;f[0]=f[1]=1;for(int i=2;i<=n;++i){f[i]=f[i-1]+f[i-2];}cout<<f[n]<<endl;ll a=1,b=1,c=1;for(int i=2;i<=n;++i){c=a+b;a=b;b=c;}cout<<c<<endl;return 0;
}
二维递推以杨辉三角为例:
#include <iostream>
using namespace std;
typedef long long ll;
const int N = 55;
ll f[N][N];
void init(){for(int i=1;i<N;++i){for(int j=1;j<=i;++j){if(j==1){f[i][j]=1;}else{f[i][j]=f[i-1][j-1]+f[i-1][j];}}}
}
int main () {init();int n,m;cin>>n>>m;cout<<f[n][m]<<endl;return 0;
}