zoukankan      html  css  js  c++  java
  • 【FJOI2016】建筑师

    题面

    https://www.luogu.org/problem/P4609

    题解:首先注意到整个“建筑群”被最高的建筑分成两部分,两部分相对独立。

    把第一类斯特林数的环变成强制以最大值为头的序列,这样一个盒子代表了一个楼房和被它遮盖的楼房的集合。

    所以只要有$a+b-2$个这样的集合,然后把其中的$a-1$个分给左侧,$b-1$个分给右侧就可以了。

    为什么不组合数不乘在楼房数上?因为我只考虑了一个斯特林数。

    1. 第一类斯特林数的递推边界条件:$S1[0][0]=1$($i$,$j$都从$1$开始),我的写法是左小右大,在$i$>$j$时,$S1[i][j]=0$。
    2. 杨辉三角形处理组合数的时候,注意我通常的写法是左边大右边小的,如果调出来发现答案是$0$,可以看看是不是这里写错了。
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define mod 1000000007
    #define LL long long 
    #define ri register int
    
    using namespace std;
    
    inline int read() {
      int ret=0,f=0; char ch=getchar();
      while (ch<'0' || ch>'9') f|=(ch=='-'),ch=getchar();
      while (ch>='0' && ch<='9') ret*=10,ret+=ch-'0',ch=getchar();
      return f?-ret:ret;
    }
    
    int T,n,a,b;
    int s1[250][50500],c[250][250];
    
    int main() {
      T=read();
      s1[0][0]=1;
      for (ri i=1;i<=230;i++)
        for (ri j=1;j<=50050;j++) s1[i][j]=(s1[i-1][j-1]+(s1[i][j-1]*1LL*(j-1))%mod)%mod;
      c[0][0]=1;
      for (ri i=1;i<=230;i++)
        for (ri j=0;j<=i+1;j++) c[i][j]=(((j==0)?0:c[i-1][j-1])+c[i-1][j])%mod;
      while (T--) {
        n=read(); a=read(); b=read();
        printf("%d
    ",(s1[a+b-2][n-1]*1LL*c[a+b-2][a-1])%mod);
      }
      return 0;
    }
  • 相关阅读:
    windows下php扩展存在但无法加载的问题
    mysql5.7主从(Master/Slave)同步配置
    windows使用composer.phar
    git untrack file
    git常见问题
    thinkphp框架中Model对象$origin对象的作用
    thinkphp常见问题
    git合并多个commit
    ajax请求post和get的区别以及get post的选择
    .htaccess跳转https
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11450612.html
Copyright © 2011-2022 走看看