zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    27. Remove Element
    列表变成字典
    1. Two Sum
    CVPR2019:What and How Well You Performed? A Multitask Learning Approach to Action Quality Assessment
    959. Regions Cut By Slashes
    118. Pascal's Triangle
    loj3117 IOI2017 接线 wiring 题解
    题解 NOI2019 序列
    题解 省选联考2020 组合数问题
    题解 Educational Codeforces Round 90 (Rated for Div. 2) (CF1373)
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10303950.html
Copyright © 2011-2022 走看看