您的位置:首页 > 其它

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

2011-08-08 08:43 316 查看
hdu 2044 一只小蜜蜂...

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

#include<stdio.h>



__int64
d[53];

intmain()

{

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
。从两个方面考虑:

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

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

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

#include<stdio.h>

__int64 d[53];

intmain()

{

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];

intmain()

{

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的牛肉串最后一个字符不是'O',d2
表示长度为n的牛肉串最后一个字符是'O'。这样结果就是d1
+d2


对于已经得到了长度为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];

intmain()

{

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-1)*(d[n-1]+d[n-2])

#include<stdio.h>

double d[23],a[23];

intmain()

{

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;

}

intmain()

{

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];

intmain()

{

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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: