Description
求(n(nleq15))维空间中的(m(mleq150))个球最多将空间划分成几部分。
Solution
记录(ans[k][i])表示(k)维空间中的(i)个球最多将空间划分为几部分。
一维情况非常简单,(ans[1][i]=2i)。一维上的球就是两个点。
接下来考虑二维情况。假设现在有(x)个圆,要加入一个新圆。这个新圆可以与之前的每个圆相交,共有(2x)个交点,圆弧被分成(2x)份。这(2x)个圆弧都将其所在部分一分为二,也就增加了(2x)个部分。(ans[2][i]=i^2-i+2)。
然后考虑三维情况。现在有(x)个球,要加入一个新球。这个新球可以与之前的每个球相交,每两个球会交出一个圆,那么新球的球面就被(x)个圆划分成(ans[2][x])个曲面。这(ans[2][x])个曲面都将其所在部分一分为二,也就增加了(ans[2][x])个部分。(ans[3][x+1]=ans[3][x]+ans[2][x])。
...于是我们发现了一些规律。一个(k)维球会与(i)个(k)维球交出(i)个(k-1)维球,会增加(ans[k-1][i])个部分,即(ans[k][i+1]=ans[k][i]+ans[k-1][i])。有初值(ans[k][0]=1),那么我们可以递推得到(ans[n][m])。
时间复杂度(O(nm))。
Code
//[HNOI2006]花仙子的魔法
#include <cstdio>
long long ans[20][200];
int main()
{
int n,m; scanf("%d%d",&m,&n);
for(int i=1;i<=n;i++) ans[i][0]=1;
for(int i=1;i<=m;i++) ans[1][i]=i+i;
for(int k=2;k<=n;k++)
for(int i=1;i<=m;i++) ans[k][i]=ans[k][i-1]+ans[k-1][i-1];
printf("%lld
",ans[n][m]);
return 0;
}