递推可以说是动态规划的核心思想,下面总结了杭电上几道比较简单的递推题目:
HDU2041 超级楼梯:
题目大意:有n阶台阶,你在第一阶,每次只能向上走一步或两步,问你上到第n阶一共有多少种不同的方法数。
易知M=2时N=1,M=3时N=2,M>3时,有F【M】=F【M-1】+F【M-2】,即到达第M阶楼梯的方法数等于到达M-1阶楼梯的数目加上到达M-2阶楼梯的数目。
实质就是斐波那契数列,鉴于n的范围比较小,打表就行。
#include <cstdio> #include <iostream> using namespace std; int ans[45]; void init() { ans[2]=1; ans[3]=2; for(int i=4;i<42;i++) ans[i]=ans[i-1]+ans[i-2]; } int main() { init(); int t,n; cin>>t; while(t--) { scanf("%d",&n); printf("%d\n",ans[n]); } return 0; }
HDU2044 一只小蜜蜂:
这题和2041实质是一样的,把从a到b的路线数看为从1到b-a+1的路线数的话,其实就是斐波那契数列。
#include <cstdio> #include <iostream> using namespace std; long long ans[55]; void init() { ans[2]=1; ans[3]=2; for(int i=4;i<52;i++) ans[i]=ans[i-1]+ans[i-2]; } int main() { init(); int t,a,b; cin>>t; while(t--) { scanf("%d%d",&a,&b); cout<<ans[b-a+1]<<endl; } return 0; }
HDU2045 不容易系列之(3)—— LELE的RPG难题:
题目大意:有一排n个方格,每个方格用红,粉,绿三种颜色之一涂,要求每两个相邻的方格不能同色,同时第一个方格和最后一个方格也不能同色,问你一共有多少种不同的涂法。
对于第i个方格来说,它的涂法f(i)取决于第i-1个方格的颜色和第1个方格的颜色,如果第i-1个方格的颜色和第一个方格不同色,那么第i个方格就只有一种涂法了,有f(i)=1*f(i-1);如果第i-1个方格和第一个方格同色,那么我们就不用考虑这一格了,同时第i个方格有2种不同的涂法,有f(i)=2*f(i-2);由加法原理我们就得出了递推公式:f(n)=f(n-1)+2*f(n-2);注意把f(1)=1,f(2)=f(3)=6初始化就行了,对于f(3)还是比较特殊的。
#include <cstdio> #include <iostream> using namespace std; int main() { long long f[51]; int n,i; f[1]=3; f[2]=6; f[3]=6; for(i=4;i<=50;i++) f[i]=f[i-1]+2*f[i-2]; while(scanf("%d",&n)!=-1) cout<<f[n]<<endl; return 0; }
HDU2046 骨牌铺方格:
#include <cstdio> #include <iostream> using namespace std; long long ans[55]; void init() { ans[1]=1; ans[2]=2; for(int i=3;i<52;i++) ans[i]=ans[i-1]+ans[i-2]; } int main() { init(); int n; while(scanf("%d",&n)!=-1) cout<<ans[n]<<endl; return 0; }
HDU2047 阿牛的EOF牛肉串:
对于下一个字符,分两种情况考虑:
(1)是“O”,那么前一个字母肯定不是‘O’,方法数等于2乘上前n-2个的方法数,即f(n)=2*f(n-2);
(2)不是“O”,那么就有“E”和“F”这两种情况,再乘上前n-1个的方法数,即f(n)=2*f(n-1);
根据加法原理:f(n)=2*(f(n-1)+f(n-2));
#include <cstdio> #include <iostream> using namespace std; int main() { long long f[41]; int n,i; f[1]=3; f[2]=8; for(i=3;i<=40;i++) f[i]=2*(f[i-1]+f[i-2]); while(scanf("%d",&n)!=-1) cout<<f[n]<<endl; return 0; }