hdu 递推 2050 1290 2563 2064 2077 规律哥

来源:互联网 发布:网络出版许可证查询 编辑:程序博客网 时间:2024/05/24 05:45

(没有质量,就出数量) 转载出处:http://blog.sina.com.cn/s/blog_7fec19cd01010h60.html

 

hdu2050 折线分平面:

1.当有n-1条直线时,平面最多被分成了fn-1)个区域。则第n条直线要是切成的区域数最多,就必须与每条直线相交且不能有同一交点。这样就会得到n-1个交点。这些交点将第n条直线分为2条射线和n-2条线断。而每条射线和线断将以有的区域一分为二。这样就多出了2+n-2)个区域。

故:f(n)=f(n-1)+n

=f(n-2)+(n-1)+n

……

=f(1)+1+2+……+n

=n(n+1)/2+1

2.根据直线分平面可知,由交点决定了射线和线段的条数,进而决定了新增的区域数。当n-1条折线时,区域数为fn-1)。为了使增加的区域最多,则折线的两边的线段要和n-1条折线的边,即2*n-1)条线段相交。那么新增的线段数为4*n-1),射线数为2。但要注意的是,折线本身相邻的两线段只能增加一个区域。

故:f(n)=f(n-1)+4(n-1)+2-1

=f(n-1)+4(n-1)+1

=f(n-2)+4(n-2)+4(n-1)+2

……

=f(1)+4+4*2+……+4(n-1)+(n-1)

=2n^2-n+1

代码:

#include<stdio.h>
int f[10009];
int main()
{
int t,n,i;
f[1]=2;
for(i=2;i<=10000;i++)
f[i]=f[i-1]+4*(i-1)+1;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
printf("%d\n",f[n]);
}
return 0;
}

hdu1290 平面分割空间问题:

由二维的分割问题可知,平面分割与线之间的交点有关,即交点决定射线和线段的条数,从而决定新增的区域数。试想在三维中则是否与平面的交线有关呢?当有n-1个平面时,分割的空间数为fn-1)。要有最多的空间数,则第n个平面需与前n-1个平面相交,且不能有共同的交线。即最多有n-1条交线。而这n-1条交线把第n个平面最多分割成gn-1)个区域。(gn)为(1)中的直线分平面的个数)此平面将原有的空间一分为二,则最多增加gn-1)个空间。

故:f=f(n-1)+g(n-1) ps:g(n)=n(n+1)/2+1

=f(n-2)+g(n-2)+g(n-1)

……

=f(1)+g(1)+g(2)+……+g(n-1)

=2+(1*2+2*3+3*4+……+(n-1)n)/2+n-1

=(1+2^2+3^2+4^2+……+n^2-1-2-3-……-n)/2+n+1

=(n^3+5n)/6+1

hdu 2563:

a[n]是向上走n步的方法数,b[n]是向左或向右走的方法数,则a[n]=a[n-1]+b[n-1],

b[n]=2*a[n-1]+b[n-1]。因为之前的向上可以走两个方向,而之前的向左或者向右只能继续按照原来的方向走,因为走过的路会消失。

因为f[n]=a[n]+b[n],

f[n]=3*a[n-1]+2*b[n-2]=2*f[n-1]+a[n-1]=2*f[n-1]+f[n-2]。

Hdu 2064:汉诺塔III

题中改变了原有的汉诺塔规则,而是 每次必须经过中间的柱子,尽管有些许变化但是推到过程是一样的(现设有ABC三个柱子,以及标号为1-N的盘子),既然不能将编号为N的盘子移动到C上,那么就必须先移动NB上,这样的话就先有N-1个盘子在C上这个状态,然后在移动NC上之前又要把N-1个盘子移动到A上,要达到最终目的的话,就要再把N-1个盘子移动到C上。

上述过程就得到一个递推式 F[N]= 3* F[N-1]+ 2, F[N]=3^N-1

代码:

#include<stdio.h>

int main()
{
int i,n;
__int64 f[36];
f[1]=2;
for(i=2;i<=35;i++)
f[i]=3*f[i-1]+2;
while(scanf("%d",&n)!=-1)
{
printf("%I64d\n",f[n]);
}
return 0;
}

Hdu 2077:汉诺塔IV

2064中设n个盘子需要g(n)步,则g(n)=3*g(n-1)+2,很好想,从而得通项公式g(n)=3^n-1;2077中加了一个条件,难想一些,为了便于说明,我们把三根柱子分别记为柱A、柱B、柱C,第n个盘子记为盘n,那么最优情况肯定是先把上面n-2个盘子移到柱C上,再把盘n-1和盘n依次移到柱B上,然后把柱C上的n-2个盘子移回柱A,接着把盘n-1和盘n移到柱C上,最后再把n-2个盘子移到柱C即可,这个过程中,把n-2个盘子从柱A移到柱C(或反向移动)的过程与2064题是完全一样的。故移动n个盘子的步数f(n)=3*g(n-2)+4,代入上而的通项公式得

f(n)=3^(n-1)+1=3*f[n-1]-2。

代码:

#include<stdio.h>
int main()
{
int t,n,i;
int f[22];
f[1]=2;
for(i=2;i<=20;i++)
f[i]=3*f[i-1]-2;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
printf("%d\n",f[n]);
}
return 0;
}

hdu 1995 汉诺塔V

从下往上,依次翻2倍:

#include<stdio.h>

__int64 f[65];

int main()

{

int t,n,k,i;

f[1]=1;

for(i=2;i<=60;i++)

f[i]=f[i-1]*2;

scanf("%d",&t);

while(t--)

{

scanf("%d%d",&n,&k);

k=n-k+1;

printf("%I64d\n",f[k]);

}

return 0;

}

原创粉丝点击