hdu 2044-2050 递推求解专题练习

来源:互联网 发布:阿里云企业简介 编辑:程序博客网 时间:2024/05/05 22:05
 hdu 2044  一只小蜜蜂...

这是个典型的斐波那契数列。往右侧的方向,可以发现与n相连的是n+1、n+2。

#include<stdio.h>

__int64
d[53];

int
main()
{

    int
i,j;
    int
cases;
    int
a,b;

    d[1]=1;
    d[2]=1;
    for
(
i=3;i<=50;i++)
        d[i]=d[i-1]+d[i-2];

    scanf("%d",&cases);

    while
(
cases--)
    {

        scanf("%d%d",&a,&b);
        printf("%I64d\n",d[b-a+1]);
    }

    return
0;
}

注意要用__int64.

 

hdu 2045  不容易系列之(3)—— LELE的RPG难题

首先因为有三种颜色,我们先枚举出当方格有1,2,3个时。然后再考虑>3个方格时的情况。如果长度是n(n>3),我们需要求解d[n]。从两个方面考虑:

已经得到了d[n-1],也就是对于放好的n-1个格子的颜色,我们可以知道在第n个位置能放的颜色也就是确定的。因为这个第n-1的格子的颜色不与第一个相同,也不与相连的格子颜色相同;

对于已经得到的d[n-2],也就是对于放好了n-2个格子的颜色,我们可以在第n-1个位置放与第一个格子相同的颜色,然后在第n个位置上可以放两种颜色了,因为与他相连的n-1以及1位置上的颜色是一样的。

所以,d[n]=d[n-1]+d[n-2]*2

#include<stdio.h>
__int64
d[53];

int
main()
{

    int
i,j;
    int
n;

    d[1]=3;
    d[2]=6;
    d[3]=6;

    for
(
i=4;i<=50;i++)
        d[i]=d[i-1]+d[i-2]*2;

    while
(
scanf("%d",&n)!=EOF)
    {

        printf("%I64d\n",d[n]);
    }


    return
0;
}

hdu 2046  骨牌铺方格

这也是个斐波那契数列。固定第n个方格是竖着的,可以得到d[n-1]中;以及固定后面两个方格是这样横向放着的,那么可以得到d[n-2]中放法。

#include<stdio.h>
__int64
d[53];

int
main()
{

    int
i,j;
    int
n;

    d[1]=1;
    d[2]=2;

    for
(
i=3;i<=50;i++)
        d[i]=d[i-1]+d[i-2];

    while
(
scanf("%d",&n)!=EOF)
    {

        printf("%I64d\n",d[n]);
    }


    return
0;
}

hdu 2047 阿牛的EOF牛肉串

我用到了两个数组,d1[n]表示长度为n的牛肉串最后一个字符不是'O',d2[n]表示长度为n的牛肉串最后一个字符是'O'。这样结果就是d1[n]+d2[n];

对于已经得到了长度为n-1的牛肉串,我们可以来讨论在第n个位置放置何种字符的牛肉串。

已得到第n-1个位置的字符第n个位置需要放置的字符结果不是'O'不是'O'得到长度为n的,结尾不是'O'的字符串不是'O'是'O'得到长度为n的,结尾是'O'的字符串是'O'不是'O'得到长度为n的,结尾不是'O'的字符串是'O'是'O'不成立

所以,动态规划方程就很容易得出来了。

#include<stdio.h>
__int64
d1[43],d2[43];

int
main()
{

    int
i;
    int
n;

    d1[1]=2;
    d2[1]=1;

    for
(
i=2;i<=40;i++)
    {

        d1[i]=d1[i-1]*2+d2[i-1]*2;
        d2[i]=d1[i-1];
    }


    while
(
scanf("%d",&n)!=EOF)
    {

        printf("%I64d\n",d1[n]+d2[n]);
    }

    return
0;
}

 

hdu 2048 神、上帝以及老天爷

错排。对于错排,也是很经典的递推。我们可以这样去考虑。假设已经得到了n-1的人的错排情况。现在来讨论第n个人加入进来时的错排。

如果把n排到第k(k!=n)个位置,那么有两种情况。一、如果第k个人占据第n个位置。那么就变成了n-2个人的错排情况了;二、如果第k个人不占据第n个位置,而此时n占据了k的位置,我们现在完全可以假设k的号码就是n(因为k不能占据n的位置),这样就变成了n-1个人的错排情况了。最后这个k可以是前面n-1个人中的任意一个人。所以,就可以得到递推公式d[n]=(n-1)*(d[n-1]+d[n-2])

#include<stdio.h>
double
d[23],a[23];

int
main()
{

    int
cases,n;
    int
i;
    d[1]=0;
    d[2]=1;

    for
(
i=3;i<=20;i++)
        d[i]=d[i-2]*(i-1)+d[i-1]*(i-1);

    a[1]=1;
    a[2]=2;
    for
(
i=3;i<=20;i++)
        a[i]=a[i-1]*i;

    scanf("%d",&cases);
    while
(
cases--)
    {

        scanf("%d",&n);
        printf("%.2lf%%\n",d[n]/a[n]*100);
    }

    return
0;
}

 

 

hdu  2049 不容易系列之(4)——考新郎

这个题目主要也是错排

#include<stdio.h>
__int64
d[22];
__int64
c[22][22];

void
init()
{

    int
i,j;
    d[1]=0;
    d[2]=1;

    for
(
i=3;i<=20;i++)
        d[i]=d[i-1]*(i-1)+d[i-2]*(i-1);

    for
(
i=0;i<=20;i++)
        c[i][0]=1;
    for
(
i=0;i<=20;i++)
        c[i][i]=1;
    for
(
i=2;i<=20;i++)
        for
(
j=1;j<=20;j++)
            c[i][j]=c[i-1][j-1]+c[i-1][j];


    return
;
}


int
main()
{

    int
cases;
    int
n,m;

    init();
    scanf("%d",&cases);

    while
(
cases--)
    {

        scanf("%d%d",&n,&m);
        printf("%I64d\n",c[n][m]*d[m]);
    }

    return
0;
}

 

hdu 2050 折线分割平面

这个不知道怎么说,我主要是找到当多画一条折线时,是那些地方多出来了,哪些又可以取代以前的平面。

 

图中的线画得有三根线不见了(图中有六条水平的直线)。图中模拟的是,当第四条折线画上去的时候情况。黑点区域可以表示以前的平面;红点区域表示新增的平面。这样去画水平线模拟,很容易找到规律了。

#include<stdio.h>
__int64
d[10003];

int
main()
{

    int
cases;
    int
n,i;

    d[1]=2;
    for
(
i=2;i<=10000;i++)
        d[i]=d[i-1]+4*(i-1)+1;
    scanf("%d",&cases);

    while
(
cases--)
    {

        scanf("%d",&n);
        printf("%I64d\n",d[n]);
    }

    return
0;
}

 

 

 

 

原创粉丝点击