(没有质量,就出数量) 转载出处:http://blog.sina.com.cn/s/blog_7fec19cd01010h60.html
hdu2050 折线分平面:
1.当有n-1条直线时,平面最多被分成了f(n-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条折线时,区域数为f(n-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个平面时,分割的空间数为f(n-1)。要有最多的空间数,则第n个平面需与前n-1个平面相交,且不能有共同的交线。即最多有n-1条交线。而这n-1条交线把第n个平面最多分割成g(n-1)个区域。(g(n)为(1)中的直线分平面的个数)此平面将原有的空间一分为二,则最多增加g(n-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
题中改变了原有的汉诺塔规则,而是 每次必须经过中间的柱子,尽管有些许变化但是推到过程是一样的(现设有A,B,C三个柱子,以及标号为1-N的盘子),既然不能将编号为N的盘子移动到C上,那么就必须先移动N到B上,这样的话就先有N-1个盘子在C上这个状态,然后在移动N到C上之前又要把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;
}