• BZOJ 1197 [HNOI2006]花仙子的魔法 (数学题)


    题面:洛谷传送门 BZOJ传送门

    非常有意思的一道数学题,浓浓的$CF$风,然而我并没有想出来..

    我们想把一个$n$维空间用$n$维球分成尽可能多的块

    而新增加一个$n$维球时,肯定要尽可能多地切割前几个球围成的不同空间

    画画图容易发现$n=1$的规律,因为一条线段只能在两个端点处切割这条直线,所以$f(n)=2n$

    $n=2$的规律不太好找,但突破口也在这了..

    发现当一个新的圆加入到图里时,新圆会切割原来的圆,把原图分成了更多的小块

    我们把新圆的圆周看成一条线段,把旧圆和新圆的两个交点形成的弧看成一条线段

    诶?问题似乎变成了一维的,事实上我们是再用一个新的直线去切原来的直线

    原来直线数目是$(i-1)$,因此$f[i]=f[i-1]+2(i-1)$

    那如果把这个问题推广到更高的维度呢?

    结论还是成立的,我们在i维空间内,用一个$i$维球去切$j-1$个$i$维球

    新产生的块数目就是用$i-1$维球去切$j-1$个$i-1$维球

    因此得到递推式$f[i,j]=f[i-1,j-1]+f[i,j-1]$

     1 #include <cmath>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #define N1 105
     6 #define ll long long
     7 #define ull unsigned long long 
     8 #define dd double
     9 #define inf 0x3f3f3f3f
    10 using namespace std;
    11 
    12 int gint()
    13 {
    14     int ret=0,fh=1;char c=getchar();
    15     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
    16     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
    17     return ret*fh;
    18 }
    19 
    20 ull f[N1][N1];
    21 int n,m;
    22 
    23 int main()
    24 {
    25     scanf("%d%d",&m,&n); int i,j;
    26     for(i=1;i<=n+1;i++)
    27         for(j=2,f[i][1]=2;j<=m;j++)
    28             f[i][j]=f[i-1][j-1]+f[i][j-1];
    29     printf("%llu
    ",f[n+1][m]);
    30     return 0;
    31 }
  • 相关阅读:
    SVN操作异常
    VS2010安装MVC3
    (转)游戏类型
    (转)32位汇编指令 寄存器
    (转)#pragma 用法
    (转)UI库
    (转)简单实用的网游服务器架构
    (转)一个客户端网游市场分布的数据
    (转)源于魔兽!《植物大战僵尸》成功奥秘
    (转)【分析】中国网游行业上市公司投资分析之网易
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10303950.html
Copyright © 2020-2023  润新知