动态规划之简单递推(HDU2041,HDU2044,HDU2045,HDU2046,HDU2047)

递推可以说是动态规划的核心思想,下面总结了杭电上几道比较简单的递推题目:

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 

#include 
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 
#include 
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<


 

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 
#include 
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<



HDU2046    骨牌铺方格:

#include 
#include 
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<



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 
#include 
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<

你可能感兴趣的:(DP)