(没有质量,就出数量) 转载出处: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()
{
}
hdu1290
由二维的分割问题可知,平面分割与线之间的交点有关,即交点决定射线和线段的条数,从而决定新增的区域数。试想在三维中则是否与平面的交线有关呢?当有n-1个平面时,分割的空间数为f(n-1)。要有最多的空间数,则第n个平面需与前n-1个平面相交,且不能有共同的交线。即最多有n-1
故:f=f(n-1)+g(n-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
=(n^3+5n)/6+1
hdu
设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
题中改变了原有的汉诺塔规则,而是
上述过程就得到一个递推式
代码:
#include<stdio.h>
int main()
{
}
Hdu
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()
{
}
从下往上,依次翻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;
}